177 Commits
Author SHA1 Message Date
Gatsby Van a24d8e8d35 update (GJB8114) 2024-07-04 11:01:59 +08:00
Gatsby Van 3e7060965e misc update: make it more conform with GJB-8114 2024-06-27 13:37:51 +08:00
Gatsby Van fd9e7f54eb update make file 2024-06-25 11:00:10 +08:00
Gatsby Van f8212892a2 avoid usage of goto` 2024-06-25 10:59:54 +08:00
bit-cyber-fh 884d9bcca9 update hardware validation constrain 2024-06-12 10:28:38 +08:00
Gatsby Van 5af74419e0 update calibration data script. 2024-06-10 21:46:03 +08:00
Gatsby Van f0b28b55fb update calibration data 2024-06-10 21:23:59 +08:00
bit-cyber-fh 97b8f28e70 update calibration data (add LJ02) 2024-05-23 18:23:06 +08:00
bit-cyber-fh 608bbf1cfa add LJ06 calibration data 2024-05-23 18:16:56 +08:00
bit-cyber-fh 711cb50658 Merge branch 'master' of http://nas.gatsby.icu:3000/gatsby/df_datalink 2024-05-23 18:16:15 +08:00
bit-cyber-fh 746e87df86 add calibration data 2024-05-23 18:14:24 +08:00
bit-cyber-fh fa24e0f109 add 9361 rx gain config 2024-05-23 18:11:36 +08:00
bit-cyber-fh 40fdf13fd1 Revert "misc update"
This reverts commit 268e724c72ca625fadaad6897a273ffc21e3f723.
2024-05-23 18:06:34 +08:00
bit-cyber-fh 55cd53b746 misc update 2024-05-23 18:03:29 +08:00
bit-cyber-fh c7c81ddb83 clear calibration data 2024-05-23 17:42:42 +08:00
bit-cyber-fh 52f9390981 Merge branch 'master' of http://nas.gatsby.icu:3000/gatsby/df_datalink 2024-05-23 17:41:46 +08:00
bit-cyber-fh 475a625663 update calibration data 2024-05-23 17:41:41 +08:00
bit-cyber-fh 7b36324101 update calibration data 2024-05-23 17:38:09 +08:00
Gatsby Van c9f827661b misc update 2024-05-23 11:25:39 +08:00
bit-cyber-fh 475314f2a5 Merge branch 'master' of http://nas.gatsby.icu:3000/gatsby/df_datalink 2024-05-22 16:22:38 +08:00
bit-cyber-fh 68396cb7ac misc update 2024-05-22 16:22:18 +08:00
Gatsby Van 688534c117 *bugfix: correct head node default cxn2Net value 2024-05-20 19:14:41 +08:00
Gatsby Van 98ec0e7855 *add calibration data 2024-05-20 17:15:59 +08:00
bit-cyber-fh 45a13b9c5d *add calibration data 2024-05-20 17:05:42 +08:00
Gatsby Van f7f3d76d9a simplified makecopy 2024-04-19 17:47:05 +08:00
bit-cyber-fh f8985df185 update calibration data 2024-04-19 17:33:00 +08:00
bit-cyber-fh fdc37dab4a pluginUpdate: add node id pint 2024-04-07 17:01:15 +08:00
bit-cyber-fh cfc538bd4d bugfix: avoid confirm frame reception missing 2024-04-07 16:57:29 +08:00
Gatsby Van da1659a582 misc update 2024-04-02 00:17:39 +08:00
bit-cyber-fh f363d3afba misc update 2024-04-02 00:05:54 +08:00
bit-cyber-fh ff4b609a37 *add physical ID 2024-04-02 00:05:35 +08:00
bit-cyber-fh bbdaa49d53 *add calibration setting 2024-04-02 00:04:21 +08:00
bit-cyber-fh 06169451f8 misc update 2024-03-28 16:15:26 +08:00
bit-cyber-fh c763f1a481 misc update 2024-03-28 15:59:02 +08:00
bit-cyber-fh 8d72288675 Better struct comment 2024-03-28 15:58:15 +08:00
bit-cyber-fh 16d1ad30a7 unified indentation 2024-03-28 15:25:58 +08:00
Gatsby Van 8779c9855e omit hopping pattern configure methods 2024-03-28 11:04:29 +08:00
bit-cyber-fh 69a8d9d36d Update Comment: Better Doxygen Style 2024-03-28 11:00:12 +08:00
Gatsby Van 41964520a8 misc fix 2024-03-28 00:05:34 +08:00
bit-cyber-fh bab91e13df Common Update: Better Doxygen Style 2024-03-28 00:00:59 +08:00
Gatsby Van 9b416114a1 BSP update: trim unnecessary memory 2024-03-25 13:14:52 +08:00
Gatsby Van e7b45ae1f5 BSP update: trim unnecessary memory 2024-03-24 22:13:44 +08:00
Gatsby Van 3edfce69f2 update physical layer logging scheme 2024-03-24 22:13:22 +08:00
Gatsby Van ad3bc29cfa trim trailing space 2024-03-24 22:05:15 +08:00
Gatsby Van 02fd467708 update test data 2024-03-24 22:04:48 +08:00
Gatsby Van 1fc4fad5ea Merge remote-tracking branch 'refs/remotes/origin/master' 2024-03-22 10:32:07 +08:00
Gatsby Van 957672a191 add test data 2024-03-21 16:22:47 +08:00
Gatsby Van 807b045b75 code simplification 2024-03-20 16:24:05 +08:00
Gatsby Van 6f4774f6b8 add missing logging update 2024-03-20 15:57:21 +08:00
Gatsby Van de5759b392 *add feature: frame type specialized attenuation 2024-03-20 15:14:50 +08:00
Gatsby Van 2b18765563 misc update 2024-03-18 20:21:46 +08:00
Gatsby Van 03a6d86a3a remove unused variables 2024-03-18 11:04:41 +08:00
Gatsby Van 729bbeb60e format and cleanup 2024-03-18 11:02:20 +08:00
Gatsby Van 33545b63e1 config logic simplification 2024-03-18 11:01:56 +08:00
Gatsby Van 6c64421336 update scan frame handling schedule 2024-03-18 11:00:22 +08:00
Gatsby Van dda9d09f2a new linklayer api L2_isStarted 2024-03-18 10:58:16 +08:00
Gatsby Van 14f2be3053 update link brock threshold 2024-03-18 10:57:49 +08:00
Gatsby Van b7607a7a1b cleanup and misc update 2024-03-16 16:57:21 +08:00
Gatsby Van c07cd00f2f comment update and cleanup 2024-03-16 16:26:03 +08:00
Gatsby Van 20da80f6c2 update packet logging method 2024-03-16 16:25:44 +08:00
Gatsby Van c7e3eb2800 *shorten time frame length 2024-03-16 16:20:39 +08:00
Gatsby Van 9acdd0609a update svcFSM 2024-03-16 16:19:15 +08:00
Gatsby Van 66529637a3 add comment add enhance code coherent 2024-03-16 16:18:03 +08:00
Gatsby Van 62cc15c3d4 add beampattern refreash method 2024-03-16 13:20:04 +08:00
Gatsby Van 98e6935d9a *bugfix: add missing beam steer 2024-03-16 13:19:42 +08:00
Gatsby Van 0c6d861620 cleanup 2024-03-16 13:18:16 +08:00
Gatsby Van f6c2568a75 update scan frame content 2024-03-14 21:39:22 +08:00
Gatsby Van ef1c41b500 update beam scan scheme 2024-03-14 21:24:22 +08:00
Gatsby Van 9a7b89ca82 correct slave node beam setting 2024-03-14 21:22:29 +08:00
Gatsby Van 80035d5208 omit redunsant code 2024-03-14 21:21:57 +08:00
Gatsby Van ab7ce2e082 update plugin 2024-03-14 21:21:23 +08:00
Gatsby Van f5aca7d5cf update MPC 2024-03-13 17:01:07 +08:00
Gatsby Van c3e0c7a66a clean uo & enhance coherence 2024-03-12 20:49:24 +08:00
Gatsby Van 2898bdfa15 add MPC module to GE project 2024-03-12 20:43:15 +08:00
Gatsby Van 31dcb5aa69 delete systembus module from GE project 2024-03-12 20:42:57 +08:00
Gatsby Van a1fc87dc97 enhance readability 2024-03-12 20:41:59 +08:00
Gatsby Van 009ddfd895 fix typo 2024-03-12 20:39:38 +08:00
Gatsby Van 222dcb789c update bsp: add MPC 2024-03-12 17:23:00 +08:00
Gatsby Van 6b016e1181 update systembus: omit redundant code 2024-03-12 11:20:56 +08:00
Gatsby Van 712d37061a add antenna power mode print 2024-03-07 11:42:22 +08:00
Gatsby Van dfecadac56 omit redundant code 2024-03-07 11:41:52 +08:00
Gatsby Van c09bd57408 enhance code inherence 2024-03-07 11:40:53 +08:00
Gatsby Van ec772ba9e3 add new log entry (phy: antenna power mode) 2024-03-07 11:40:53 +08:00
Gatsby Van 51b96825a3 formatted document 2024-03-06 20:25:43 +08:00
Gatsby Van 274ee8922e bugfix: missing semicolon 2024-03-06 20:18:50 +08:00
Gatsby Van 8c12c0e755 Merge remote-tracking branch 'origin' 2024-03-06 20:16:09 +08:00
Gatsby Van 1e5f8052e5 plugin update: new lowpower and silient command 2024-03-06 20:08:33 +08:00
Gatsby Van 10c72585de *add new silent command 2024-03-06 20:03:38 +08:00
Gatsby Van c3e47b0fae correct time stamp 2024-03-06 20:03:15 +08:00
Gatsby Van 60033f36a7 omit redundant code 2024-03-06 20:02:38 +08:00
Gatsby Van 582cbd57af *bugfix: ommit extra event trigger 2024-03-06 20:01:34 +08:00
Gatsby Van 34b851fab7 delete trailing blank space 2024-03-05 21:31:06 +08:00
Gatsby Van 8ffcb8b048 correct byte order 2024-03-05 21:30:44 +08:00
Gatsby Van b0067e53a6 remove redundant code 2024-03-05 21:29:56 +08:00
Gatsby Van 3073a2767b bugfix: correct line break 2024-03-05 21:01:01 +08:00
Gatsby Van 7818a754c6 update plugin: add retrieved data print 2024-03-05 20:40:41 +08:00
Gatsby Van b99d0bfca0 *bugfix: correct beam setup 2024-03-02 16:32:36 +08:00
Gatsby Van 3dedebbe79 miscellaneous update 2024-03-02 16:32:12 +08:00
Gatsby Van 22417853dd enhanced code inherence 2024-03-02 13:14:17 +08:00
Gatsby Van 633f6dff37 bugfix: correct api call 2024-03-02 13:13:20 +08:00
Gatsby Van 1192f7b4cd revise beam pattern 2024-03-01 21:27:37 +08:00
Gatsby Van 871c9882b4 add api (Phy_LastScanBeamNo) 2024-03-01 21:27:21 +08:00
Gatsby Van 04a75154c5 add beam steering 2024-03-01 21:27:00 +08:00
Gatsby Van f1e1ddf48f complete linklayer logging 2024-03-01 21:26:28 +08:00
Gatsby Van 09cc2ce347 *add antenna info configs (scan beam directions) 2024-03-01 21:25:15 +08:00
Gatsby Van 0c270df599 add antenna bram control 2024-03-01 19:25:33 +08:00
Gatsby Van 8be194a410 miscellaneous update 2024-02-22 17:31:20 +08:00
Gatsby Van ea5d6e0962 *bugfix: add missing return value 2024-02-22 16:30:25 +08:00
Gatsby Van 7edb8cb3f0 *bugfix: add hardware status to remote check 2024-02-22 16:27:22 +08:00
Gatsby Van 6299d8982d fix typo 2024-02-22 16:26:01 +08:00
Gatsby Van 8af1439087 update hopping pattern 2024-02-22 16:25:49 +08:00
Gatsby Van 95041a8395 *bugfix: correct hardware status determination 2024-02-22 16:25:32 +08:00
Gatsby Van 5cabf2ab65 add comtool python plugin 2024-02-22 16:17:43 +08:00
Gatsby Van 638b24a6a1 make compatible withe BSD sed 2024-02-21 21:06:58 +08:00
Gatsby Van 2b74942521 add hardware configuration files 2024-02-20 17:40:56 +08:00
Gatsby Van 597ea2c7cd formatted 2024-02-20 17:40:18 +08:00
Gatsby Van 6d08ee216a *split hardware configurations to individual files 2024-02-20 17:40:04 +08:00
Gatsby Van d87a4434c7 update ad temperate reading api 2024-02-20 17:39:32 +08:00
Gatsby Van c27d6fc455 adapted to new log content definition 2024-02-20 13:13:57 +08:00
Gatsby Van 0701eb6f43 *update log content 2024-02-20 13:13:28 +08:00
Gatsby Van ffc9f22694 omit redundant api 2024-02-20 13:12:49 +08:00
Gatsby Van c7898003c0 *add clock and ad status update api 2024-02-20 11:22:56 +08:00
Gatsby Van 2c45d1e5b8 add missing remote test 2024-02-01 17:09:59 +08:00
Gatsby Van 9412f65c3c *bugfix: correct memcpy offset 2024-02-01 17:09:37 +08:00
Gatsby Van c0ebef41ee *bugfix: correct type definition 2024-02-01 17:08:51 +08:00
Gatsby Van a2c6ff83f7 missing semicolon 2024-02-01 15:12:34 +08:00
Gatsby Van 73b8ee8bc5 *bugfix: correct antenna status code 2024-02-01 15:09:26 +08:00
Gatsby Van d8fbdfb8e6 *bugfix: add missing hardware status fetching 2024-02-01 15:07:48 +08:00
Gatsby Van ff87644416 trim trailing white spaces 2024-02-01 15:05:53 +08:00
Gatsby Van adcf7200bc *add new routine mode 2024-02-01 15:05:14 +08:00
Gatsby Van f71ce6bd94 add remote test response 2024-02-01 14:57:13 +08:00
Gatsby Van c8b0ca74a3 adapted to new system monitor api 2024-02-01 14:56:58 +08:00
Gatsby Van 1a413e4d06 adapted to new system monitor api 2024-02-01 14:56:28 +08:00
Gatsby Van b7a337f821 update hardware status refresh api 2024-02-01 14:55:16 +08:00
Gatsby Van 38b7f6b985 omit unused code 2024-02-01 14:54:43 +08:00
Gatsby Van 4457eb8bc1 *packed log structs 2024-02-01 14:54:13 +08:00
Gatsby Van 0248c185e4 change hardware status refresh api 2024-02-01 14:53:26 +08:00
Gatsby Van e81be59bbb omit unnecessary reconfiguration 2024-02-01 13:45:03 +08:00
Gatsby Van d0aad73ce5 *bugfix: correct register address 2024-02-01 13:42:26 +08:00
Gatsby Van c384bf9e9d *bugfix: correct frequency estimation calculating process 2024-02-01 13:42:02 +08:00
Gatsby Van 752e9b3081 *add hardware status check 2024-02-01 13:41:17 +08:00
Gatsby Van 81fdd612ce *bugfix: correct physical logging 2024-02-01 13:38:38 +08:00
Gatsby Van ad3a6be9b1 add voltage validation check 2024-02-01 13:37:41 +08:00
Gatsby Van 6a680a1291 update voltage scale 2024-02-01 13:37:27 +08:00
Gatsby Van 1f98662ee8 implement api 2024-01-31 20:22:07 +08:00
Gatsby Van 73f236bbd3 *bugfix: correct register define 2024-01-31 20:13:23 +08:00
Gatsby Van 223a772582 add register status code 2024-01-31 20:10:15 +08:00
Gatsby Van 3a99da8b76 *bugfix: name error 2024-01-31 20:09:48 +08:00
Gatsby Van d9ce3ae207 omit redundant code 2024-01-31 20:09:32 +08:00
Gatsby Van 29d5ec32cb fix warnings 2024-01-31 20:09:14 +08:00
Gatsby Van 45080efd34 service FSM add bit error rate and packet loss rate log 2024-01-31 20:08:52 +08:00
Gatsby Van b5acfcf827 add emulation option 2024-01-31 20:07:52 +08:00
Gatsby Van bf2a199f79 update config check 2024-01-31 20:07:30 +08:00
Gatsby Van 15e0fc2e39 *add physical logging 2024-01-31 19:49:30 +08:00
Gatsby Van bd51428bca *new time sync api implementation 2024-01-31 19:48:58 +08:00
Gatsby Van d15dd7ece5 *adapted to new time sync api 2024-01-31 19:47:29 +08:00
Gatsby Van e308a61abc *add service data logging 2024-01-31 19:47:11 +08:00
Gatsby Van b9e055c039 naming enhance 2024-01-31 19:46:45 +08:00
Gatsby Van 2700e7442e add new physical status registers 2024-01-31 19:46:16 +08:00
Gatsby Van 653483a68e adapted to new time sync api 2024-01-31 19:45:22 +08:00
Gatsby Van d310647fa6 *rewrite linklayer logging 2024-01-31 19:44:20 +08:00
Gatsby Van d2eee6548f redesign linklayer logging 2024-01-31 19:43:59 +08:00
Gatsby Van 28a2767efc *update time sync api 2024-01-31 19:43:29 +08:00
Gatsby Van 3dbf893347 redesign logging process 2024-01-31 19:42:25 +08:00
Gatsby Van 070face8d3 redesign logging api 2024-01-31 19:41:25 +08:00
Gatsby Van bfa0d40996 omit unused code 2024-01-31 19:41:06 +08:00
Gatsby Van 9fcfcce584 update logging content 2024-01-31 19:40:39 +08:00
Gatsby Van f8dec485c5 miscellaneous update 2024-01-31 16:41:28 +08:00
Gatsby Van b27bc16ab0 fix typo 2024-01-31 16:10:16 +08:00
Gatsby Van 99e564476b miscellaneous update 2024-01-31 16:08:27 +08:00
Gatsby Van 4d5a4ec0da adapted to new hardware status refresh api 2024-01-31 16:08:16 +08:00
Gatsby Van 2f63058882 omit redundant api 2024-01-31 16:07:41 +08:00
Gatsby Van 413c984e85 *update self test response (add full hardware status info) 2024-01-31 16:07:12 +08:00
Gatsby Van 448895866a new hardware status refresh api 2024-01-31 16:06:31 +08:00
Gatsby Van aba91e02b0 *update hardware status content. 2024-01-31 16:05:59 +08:00
Gatsby Van 56d0fd80d0 *safer api 2024-01-31 16:05:09 +08:00
Gatsby Van 6acd4b1ca0 *update hardware status logging content 2024-01-31 16:04:09 +08:00
97 changed files with 12082 additions and 5905 deletions
+2907
View File
File diff suppressed because it is too large Load Diff
+441
View File
@@ -0,0 +1,441 @@
declare -A calMap
calMap[JG01]="\{\n\
\{ 0, 406, -10530, -8223\}, \{ 0, 697, -9933, -7988\},\n\
\{ 0, 296, -10497, -8272\}, \{ 0, 515, -10264, -8093\},\n\
\{ 0, 689, -10212, -8064\}, \{ 0, 40, -10960, -8572\},\n\
\{ 0, 722, -10878, -8518\}, \{ 0, 59, -10987, -8962\},\n\
\{ 0, 56, -11264, -8770\}, \{ 0, -464, -11341, -9159\},\n\
\{ 0, 19, -10924, -8887\}, \{ 0, -669, -10927, -8679\},\n\
\{ 0, -701, -11154, -8712\}, \{ 0, -255, -10739, -8009\},\n\
\{ 0, -192, -10509, -8242\}, \{ 0, -1057, -11183, -9007\},\n\
\{ 0, -57, -10606, -8350\}, \{ 0, -719, -10949, -8880\},\n\
\{ 0, -760, -11084, -8660\}, \{ 0, -457, -10735, -8833\},\n\
\{ 0, -188, -10623, -9119\}, \{ 0, -628, -12609, -10119\},\n\
\{ 0, -434, -12714, -10225\}, \{ 0, -727, -13074, -10685\},\n\
\{ 0, -12, -12408, -10190\}, \{ 0, 33, -12790, -10624\},\n\
\{ 0, 93, -13235, -10819\}, \{ 0, -363, -13301, -11183\},\n\
\{ 0, -514, -13955, -11557\}, \{ 0, -458, -13878, -11722\},\n\
\{ 0, 93, -13086, -11726\}, \{ 0, -663, -13597, -11868\},\n\
\{ 0, 174, -12814, -11295\}, \{ 0, 121, -12278, -11150\},\n\
\{ 0, 425, -11255, -10363\}, \{ 0, 430, -11645, -10189\},\n\
\{ 0, 277, -11844, -9499\}, \{ 0, -132, -12241, -9420\},\n\
\{ 0, 448, -11934, -9612\}, \{ 0, 200, -11778, -9582\},\n\
\{ 0, -40, -12069, -9336\}, \{ 0, 1692, -11315, -9085\},\n\
\{ 0, -1753, -11445, -9482\}, \{ 0, -2520, -12620, -10068\},\n\
\{ 0, -1976, -12674, -10218\}, \{ 0, -1984, -12525, -10354\},\n\
\{ 0, -2272, -13476, -10932\}, \{ 0, -2123, -13918, -11095\},\n\
\{ 0, -2883, -14447, -11659\}, \{ 0, -2826, -13946, -11563\},\n\
\{ 0, -2697, -13680, -11328\}, \{ 0, -3068, -13393, -11614\},\n\
\{ 0, -2935, -13074, -11882\}, \{ 0, -3017, -13038, -11163\},\n\
\{ 0, -2490, -12379, -11288\}, \{ 0, -2463, -12286, -10726\},\n\
\{ 0, -2686, -12167, -10673\}, \{ 0, -2428, -12077, -10555\},\n\
\{ 0, -2282, -12564, -10388\}, \{ 0, -2017, -12303, -10844\},\n\
\{ 0, -2329, -12637, -11250\}, \{ 0, -2703, -13362, -11807\},\n\
\{ 0, -1820, -12605, -11733\}, \{ 0, 596, -10833, -9852\},\n\
\{ 0, 9, -11140, -9776\}, \{ 0, 41, -11168, -9478\},\n\
\{ 0, -261, -11368, -9752\}, \{ 0, 226, -11282, -9879\},\n\
\{ 0, -68, -11454, -10148\}, \{ 0, -314, -12278, -10716\},\n\
\{ 0, -66, -11998, -10762\}, \{ 0, -58, -11469, -10664\},\n\
\{ 0, 319, -10759, -10212\}, \{ 0, 122, -11041, -9901\},\n\
\{ 0, -269, -11085, -10008\}, \{ 0, 637, -10569, -9674\},\n\
\{ 0, 1185, -10632, -9521\}, \{ 0, 902, -11053, -9681\},\n\
\{ 0, 560, -11408, -9588\}, \{ 0, 1162, -11079, -9371\},\n\
\{ 0, 1780, -10547, -9133\}, \n\
};"
calMap[JG02]="\{\n\
\{ 0, 509, -2785, -4375\}, \{ 0, 655, -3482, -4447\},\n\
\{ 0, 520, -3231, -4651\}, \{ 0, 680, -3122, -4790\},\n\
\{ 0, 328, -3648, -4712\}, \{ 0, 260, -3454, -4515\},\n\
\{ 0, 433, -3027, -4446\}, \{ 0, 34, -4304, -4676\},\n\
\{ 0, 54, -3707, -4650\}, \{ 0, -19, -3829, -5231\},\n\
\{ 0, -156, -4018, -5292\}, \{ 0, -331, -4155, -5423\},\n\
\{ 0, -424, -4210, -5207\}, \{ 0, -592, -4131, -5572\},\n\
\{ 0, -494, -4135, -5732\}, \{ 0, -687, -4055, -5030\},\n\
\{ 0, -1000, -4456, -5228\}, \{ 0, -337, -3931, -5340\},\n\
\{ 0, -168, -3962, -5326\}, \{ 0, -852, -4534, -5798\},\n\
\{ 0, -541, -4458, -5156\}, \{ 0, -842, -5570, -6166\},\n\
\{ 0, -1490, -5883, -6645\}, \{ 0, -1036, -5917, -6151\},\n\
\{ 0, -1369, -5946, -5969\}, \{ 0, -916, -5927, -6200\},\n\
\{ 0, -521, -5595, -6066\}, \{ 0, -823, -5731, -5925\},\n\
\{ 0, -262, -5267, -5315\}, \{ 0, -697, -5434, -5676\},\n\
\{ 0, -362, -5193, -4887\}, \{ 0, -430, -5147, -4911\},\n\
\{ 0, -94, -5403, -5159\}, \{ 0, -747, -5796, -4772\},\n\
\{ 0, -679, -4909, -4531\}, \{ 0, -500, -5364, -4694\},\n\
\{ 0, -147, -5225, -4463\}, \{ 0, -283, -5815, -4360\},\n\
\{ 0, -724, -6148, -4647\}, \{ 0, -295, -6069, -4375\},\n\
\{ 0, -397, -6086, -4105\}, \{ 0, -116, -6343, -4698\},\n\
\{ 0, -589, -6398, -5353\}, \{ 0, -1068, -6640, -5014\},\n\
\{ 0, -785, -7017, -5093\}, \{ 0, -29, -6238, -5186\},\n\
\{ 0, 380, -6370, -5063\}, \{ 0, -239, -7191, -5605\},\n\
\{ 0, 321, -7256, -5177\}, \{ 0, 430, -6673, -4887\},\n\
\{ 0, 226, -7136, -5687\}, \{ 0, 142, -7175, -5498\},\n\
\{ 0, 333, -6596, -5434\}, \{ 0, 315, -6574, -5520\},\n\
\{ 0, -109, -6681, -5798\}, \{ 0, -587, -7290, -5748\},\n\
\{ 0, -229, -7105, -5463\}, \{ 0, -480, -7092, -6033\},\n\
\{ 0, -1162, -7488, -6578\}, \{ 0, -1244, -8230, -6838\},\n\
\{ 0, -941, -7941, -6976\}, \{ 0, -1181, -7816, -6868\},\n\
\{ 0, -1792, -8128, -6590\}, \{ 0, -644, -7614, -4524\},\n\
\{ 0, -873, -7358, -3775\}, \{ 0, -1250, -7370, -4506\},\n\
\{ 0, -819, -7520, -4500\}, \{ 0, -1579, -8679, -4626\},\n\
\{ 0, -1332, -7353, -4338\}, \{ 0, -1128, -7821, -5030\},\n\
\{ 0, -927, -7988, -4954\}, \{ 0, -2035, -7884, -5097\},\n\
\{ 0, -2533, -8953, -6171\}, \{ 0, -1576, -8029, -5542\},\n\
\{ 0, -1185, -7297, -5523\}, \{ 0, -2139, -8830, -6236\},\n\
\{ 0, -2137, -8976, -6225\}, \{ 0, -1387, -8252, -6043\},\n\
\{ 0, -1139, -8286, -5988\}, \{ 0, -1252, -8224, -6388\},\n\
\{ 0, -1617, -8211, -5983\}, \n\
};"
calMap[JG03]="\{\n\
\{ 0, -5670, -14728, -16999\}, \{ 0, -5942, -14703, -17077\},\n\
\{ 0, -5889, -14421, -16670\}, \{ 0, -6039, -14464, -16644\},\n\
\{ 0, -5991, -14403, -16390\}, \{ 0, -6103, -14418, -16510\},\n\
\{ 0, -5953, -14364, -16180\}, \{ 0, -6154, -14364, -16125\},\n\
\{ 0, -5945, -14263, -15929\}, \{ 0, -6075, -14327, -15930\},\n\
\{ 0, -5928, -14392, -15878\}, \{ 0, -5986, -14443, -15932\},\n\
\{ 0, -5783, -14256, -15873\}, \{ 0, -5945, -14360, -15887\},\n\
\{ 0, -5749, -14536, -15874\}, \{ 0, -5733, -14684, -15887\},\n\
\{ 0, -5630, -14594, -15987\}, \{ 0, -5752, -14743, -16002\},\n\
\{ 0, -5490, -14694, -15993\}, \{ 0, -5481, -14866, -16056\},\n\
\{ 0, -5293, -14807, -16060\}, \{ 0, -7935, -20143, -18383\},\n\
\{ 0, -7733, -20142, -18482\}, \{ 0, -7628, -20060, -18538\},\n\
\{ 0, -7437, -20112, -18495\}, \{ 0, -7314, -20012, -18544\},\n\
\{ 0, -7072, -19980, -18573\}, \{ 0, -6986, -20006, -18632\},\n\
\{ 0, -6718, -20048, -18569\}, \{ 0, -6601, -19987, -18517\},\n\
\{ 0, -6485, -20035, -18537\}, \{ 0, -6292, -20047, -18537\},\n\
\{ 0, -6105, -20153, -18482\}, \{ 0, -6081, -20314, -18501\},\n\
\{ 0, -5865, -19916, -18164\}, \{ 0, -5786, -20218, -18174\},\n\
\{ 0, -5728, -20282, -18110\}, \{ 0, -5690, -20451, -18135\},\n\
\{ 0, -5643, -20768, -18154\}, \{ 0, -5603, -20874, -18273\},\n\
\{ 0, -5621, -21190, -18095\}, \{ 0, -5522, -21547, -18146\},\n\
\{ 0, -5549, -20721, -16825\}, \{ 0, -5547, -21087, -17001\},\n\
\{ 0, -5491, -21394, -17040\}, \{ 0, -5484, -21696, -17064\},\n\
\{ 0, -5542, -22265, -17091\}, \{ 0, -5483, -22543, -17198\},\n\
\{ 0, -5460, -22748, -17254\}, \{ 0, -5417, -22961, -17307\},\n\
\{ 0, -5455, -23299, -17323\}, \{ 0, -5445, -23552, -17382\},\n\
\{ 0, -5426, -23645, -17428\}, \{ 0, -5480, -23902, -17349\},\n\
\{ 0, -5558, -24011, -17360\}, \{ 0, -5569, -24032, -17326\},\n\
\{ 0, -5614, -24067, -17305\}, \{ 0, -5656, -24000, -17251\},\n\
\{ 0, -5739, -23971, -17228\}, \{ 0, -5777, -23886, -17215\},\n\
\{ 0, -5832, -23823, -17051\}, \{ 0, -5891, -23719, -16957\},\n\
\{ 0, -6007, -23598, -16925\}, \{ 0, -5893, -20829, -15256\},\n\
\{ 0, -5886, -20669, -15091\}, \{ 0, -5883, -20496, -14990\},\n\
\{ 0, -5969, -20469, -14898\}, \{ 0, -5971, -20245, -14876\},\n\
\{ 0, -5996, -20108, -14764\}, \{ 0, -5979, -19934, -14694\},\n\
\{ 0, -5997, -19721, -14571\}, \{ 0, -6046, -19573, -14456\},\n\
\{ 0, -6001, -19418, -14381\}, \{ 0, -5942, -19239, -14265\},\n\
\{ 0, -5978, -19040, -14240\}, \{ 0, -5928, -18873, -14317\},\n\
\{ 0, -5917, -18715, -14238\}, \{ 0, -5865, -18576, -14201\},\n\
\{ 0, -5750, -18386, -14200\}, \{ 0, -5772, -18299, -14235\},\n\
\{ 0, -5754, -18187, -14300\}, \n\
};"
calMap[JG05]="\{\n\
\{ 0, 178, -7222, 8474\}, \{ 0, 218, -7139, 8383\},\n\
\{ 0, 215, -7438, 8352\}, \{ 0, 198, -7247, 8498\},\n\
\{ 0, 138, -7640, 8644\}, \{ 0, 158, -7805, 8610\},\n\
\{ 0, 135, -7804, 8531\}, \{ 0, 143, -7881, 8575\},\n\
\{ 0, 165, -8096, 8584\}, \{ 0, 118, -7962, 8558\},\n\
\{ 0, 148, -7947, 8550\}, \{ 0, 118, -8193, 8494\},\n\
\{ 0, 149, -8042, 8441\}, \{ 0, 59, -8207, 8454\},\n\
\{ 0, 101, -8029, 8575\}, \{ 0, 156, -8029, 8422\},\n\
\{ 0, 205, -8074, 8451\}, \{ 0, 167, -7912, 8405\},\n\
\{ 0, 263, -7980, 8405\}, \{ 0, 258, -8007, 8404\},\n\
\{ 0, 288, -7790, 8342\}, \{ 0, -802, -10286, 6559\},\n\
\{ 0, -717, -10120, 6574\}, \{ 0, -590, -9884, 6675\},\n\
\{ 0, -446, -9651, 6686\}, \{ 0, -371, -9600, 6700\},\n\
\{ 0, -259, -9243, 6756\}, \{ 0, -77, -9216, 6768\},\n\
\{ 0, 108, -8979, 6844\}, \{ 0, 220, -8769, 6970\},\n\
\{ 0, 348, -8820, 6991\}, \{ 0, 569, -8618, 7028\},\n\
\{ 0, 688, -8430, 7162\}, \{ 0, 798, -8520, 7293\},\n\
\{ 0, 1050, -8141, 7758\}, \{ 0, 1284, -7775, 7850\},\n\
\{ 0, 1447, -7625, 7967\}, \{ 0, 1527, -7708, 8032\},\n\
\{ 0, 1661, -7547, 8153\}, \{ 0, 1784, -7532, 8169\},\n\
\{ 0, 1863, -7560, 8430\}, \{ 0, 1977, -7617, 8609\},\n\
\{ 0, 1318, -6902, 8849\}, \{ 0, 1390, -7060, 8848\},\n\
\{ 0, 1470, -6967, 8872\}, \{ 0, 1532, -6958, 8915\},\n\
\{ 0, 1607, -7162, 8946\}, \{ 0, 1718, -7119, 9030\},\n\
\{ 0, 1781, -6970, 9113\}, \{ 0, 1807, -6943, 9071\},\n\
\{ 0, 1831, -7114, 9061\}, \{ 0, 1899, -7105, 9088\},\n\
\{ 0, 1935, -7026, 9070\}, \{ 0, 2040, -6685, 9125\},\n\
\{ 0, -8187, -6757, 9115\}, \{ 0, -10749, -6464, 9194\},\n\
\{ 0, -21024, -6513, 9071\}, \{ 0, 6072, -6529, 9040\},\n\
\{ 0, -22290, -6590, 9075\}, \{ 0, -12054, -6510, 9114\},\n\
\{ 0, -18487, -6491, 9179\}, \{ 0, -12050, -6878, 9144\},\n\
\{ 0, -4425, -6526, 9189\}, \{ 0, 2575, -4991, 10202\},\n\
\{ 0, 2566, -4792, 10308\}, \{ 0, 2596, -4920, 10513\},\n\
\{ 0, 2585, -5106, 10573\}, \{ 0, 2538, -5290, 10578\},\n\
\{ 0, 2560, -5424, 10627\}, \{ 0, 2613, -5352, 10915\},\n\
\{ 0, 2531, -5578, 10919\}, \{ 0, 2545, -5652, 11012\},\n\
\{ 0, 2646, -5819, 11079\}, \{ 0, 2661, -6046, 11136\},\n\
\{ 0, 2692, -6314, 11187\}, \{ 0, 2759, -6284, 11209\},\n\
\{ 0, 2739, -6557, 11185\}, \{ 0, 2815, -6469, 11256\},\n\
\{ 0, 2849, -6807, 11103\}, \{ 0, 2850, -6769, 11097\},\n\
\{ 0, 2923, -6999, 11232\}, \n\
};"
calMap[JG06]="\{\n\
\{ 0, -3836, -1067, 4891\}, \{ 0, -4831, -2098, 4103\},\n\
\{ 0, -4849, -1871, 4566\}, \{ 0, -4534, -1666, 4512\},\n\
\{ 0, -5764, -2767, 4245\}, \{ 0, -5591, -2123, 4174\},\n\
\{ 0, -4727, -1565, 4368\}, \{ 0, -5834, -2262, 3942\},\n\
\{ 0, -5421, -2062, 3790\}, \{ 0, -4996, -1380, 4260\},\n\
\{ 0, -5538, -1861, 3494\}, \{ 0, -5272, -1652, 3740\},\n\
\{ 0, -5561, -1802, 4038\}, \{ 0, -5320, -1734, 3742\},\n\
\{ 0, -4354, -1230, 4170\}, \{ 0, -5705, -1862, 3840\},\n\
\{ 0, -6223, -2211, 3218\}, \{ 0, -5048, -1596, 3669\},\n\
\{ 0, -5235, -1541, 3735\}, \{ 0, -6009, -2219, 3301\},\n\
\{ 0, -5545, -1879, 3686\}, \{ 0, -7174, -2853, -434\},\n\
\{ 0, -6759, -3117, 56\}, \{ 0, -7376, -3291, 221\},\n\
\{ 0, -7601, -3243, 150\}, \{ 0, -7065, -2752, -42\},\n\
\{ 0, -7701, -2828, -144\}, \{ 0, -7598, -3002, 464\},\n\
\{ 0, -7312, -2476, 399\}, \{ 0, -7939, -2374, -62\},\n\
\{ 0, -7622, -2213, 482\}, \{ 0, -6715, -1688, 1033\},\n\
\{ 0, -6755, -1445, 722\}, \{ 0, -6817, -1385, 1061\},\n\
\{ 0, -6155, -864, 1431\}, \{ 0, -6700, -1746, 1070\},\n\
\{ 0, -6973, -1127, 835\}, \{ 0, -6456, -1152, 686\},\n\
\{ 0, -6542, -1505, 1059\}, \{ 0, -6659, -1374, 584\},\n\
\{ 0, -6605, -983, 630\}, \{ 0, -6366, -1046, 800\},\n\
\{ 0, -4668, 343, 1086\}, \{ 0, -5072, 560, 468\},\n\
\{ 0, -4124, 1399, 1284\}, \{ 0, -3465, 10068, 22599\},\n\
\{ 0, -4167, 2018, 1119\}, \{ 0, -4910, 1612, 717\},\n\
\{ 0, -4917, 1600, 968\}, \{ 0, -4171, 1731, 430\},\n\
\{ 0, -3432, 13873, 166\}, \{ 0, -3571, 2840, 870\},\n\
\{ 0, -3060, 2468, 463\}, \{ 0, -2858, 2369, 373\},\n\
\{ 0, -2948, 3186, 438\}, \{ 0, -3305, 2984, -160\},\n\
\{ 0, -2027, 3128, -798\}, \{ 0, -2663, 3320, -865\},\n\
\{ 0, -3992, -562, -1509\}, \{ 0, -2913, 2844, -1081\},\n\
\{ 0, -3205, 3373, -1418\}, \{ 0, -3366, 3063, -1645\},\n\
\{ 0, -3878, 2873, -920\}, \{ 0, -1801, 6168, 2384\},\n\
\{ 0, -1252, 6409, 2308\}, \{ 0, -1724, 6027, 2474\},\n\
\{ 0, -1937, 5849, 2730\}, \{ 0, -1921, 5622, 2349\},\n\
\{ 0, -2162, 5995, -1804\}, \{ 0, -1707, 6306, 2744\},\n\
\{ 0, -1334, 5651, 3112\}, \{ 0, -2132, 5216, 2588\},\n\
\{ 0, -1878, 5912, 2448\}, \{ 0, -1233, 5205, 2467\},\n\
\{ 0, -1139, 5350, 2967\}, \{ 0, -2373, 5368, -23580\},\n\
\{ 0, -1706, 5450, 2374\}, \{ 0, -1718, 5876, 2333\},\n\
\{ 0, -1569, 5961, 2570\}, \{ 0, -1177, 6423, 2665\},\n\
\{ 0, -1210, 5976, 2608\}, \n\
};"
calMap[LJ01]="\{\n\
\{ 0, 5716, -1041, -12697\}, \{ 0, 5110, -1450, -13222\},\n\
\{ 0, 4487, -1630, -13282\}, \{ 0, 4606, -1821, -13197\},\n\
\{ 0, 4663, -2299, -13302\}, \{ 0, 4092, -2324, -13451\},\n\
\{ 0, 4233, -2419, -13189\}, \{ 0, 3702, -2961, -14147\},\n\
\{ 0, 3167, -3408, -14660\}, \{ 0, 3564, -3255, -13877\},\n\
\{ 0, 3320, -3407, -13671\}, \{ 0, 3137, -3350, -13820\},\n\
\{ 0, 3342, -3703, -13808\}, \{ 0, 3519, -3970, -14069\},\n\
\{ 0, 2983, -4415, -14335\}, \{ 0, 3636, -3825, -13840\},\n\
\{ 0, 3461, -3922, -14323\}, \{ 0, 3419, -4022, -14031\},\n\
\{ 0, 3763, -4066, -13832\}, \{ 0, 3929, -3504, -13827\},\n\
\{ 0, 3634, -4035, -14096\}, \{ 0, 3195, -6232, -14808\},\n\
\{ 0, 3428, -6179, -14913\}, \{ 0, 3506, -5525, -14510\},\n\
\{ 0, 3754, -5724, -14134\}, \{ 0, 3630, -5791, -14743\},\n\
\{ 0, 3857, -5548, -14269\}, \{ 0, 4654, -4964, -13701\},\n\
\{ 0, 4853, -4388, -13822\}, \{ 0, 4735, -4632, -13864\},\n\
\{ 0, 4981, -4381, -13979\}, \{ 0, 5528, -3984, -13626\},\n\
\{ 0, 5130, -4326, -13639\}, \{ 0, 5095, -3792, -13638\},\n\
\{ 0, 5346, -3366, -13030\}, \{ 0, 5498, -3496, -13682\},\n\
\{ 0, 5144, -3120, -13986\}, \{ 0, 5427, -2871, -12931\},\n\
\{ 0, 5939, -2824, -12646\}, \{ 0, 6030, -2983, -12662\},\n\
\{ 0, 5959, -3142, -12116\}, \{ 0, 5903, -2700, -11731\},\n\
\{ 0, 6256, -3546, -10932\}, \{ 0, 6384, -3767, -11326\},\n\
\{ 0, 6086, -3399, -11769\}, \{ 0, 5915, -3257, -12066\},\n\
\{ 0, 6257, -4021, -12273\}, \{ 0, 6084, -4192, -12153\},\n\
\{ 0, 5482, -4102, -12637\}, \{ 0, 5836, -3698, -12767\},\n\
\{ 0, 6025, -4014, -13219\}, \{ 0, 5713, -3812, -14315\},\n\
\{ 0, 5997, -3855, -14788\}, \{ 0, 5866, -3905, -15408\},\n\
\{ 0, 5328, -4627, -16458\}, \{ 0, 5686, -3646, -14885\},\n\
\{ 0, 5551, -3407, -15112\}, \{ 0, 5720, -3165, -14247\},\n\
\{ 0, 6044, -3818, -14224\}, \{ 0, 5963, -3342, -14531\},\n\
\{ 0, 6128, -3225, -13495\}, \{ 0, 6564, -3662, -13408\},\n\
\{ 0, 6000, -3479, -13609\}, \{ 0, 5876, -3190, -11817\},\n\
\{ 0, 7165, -2876, -10874\}, \{ 0, 6593, -4000, -11565\},\n\
\{ 0, 6207, -3694, -11278\}, \{ 0, 6732, -2326, -11167\},\n\
\{ 0, 6335, -3650, -11508\}, \{ 0, 6220, -4220, -12438\},\n\
\{ 0, 6069, -3838, -12545\}, \{ 0, 6182, -4635, -12472\},\n\
\{ 0, 5696, -4834, -12334\}, \{ 0, 6047, -4121, -11691\},\n\
\{ 0, 6324, -4125, -10980\}, \{ 0, 6102, -3923, -10939\},\n\
\{ 0, 6091, -3829, -10736\}, \{ 0, 5858, -4001, -10473\},\n\
\{ 0, 5473, -4773, -11209\}, \{ 0, 6045, -4642, -10361\},\n\
\{ 0, 5494, -4391, -10203\}, \n\
};"
calMap[LJ02]="\{\n\
\{ 0, -726, 598, -2561\}, \{ 0, -743, 864, -2549\},\n\
\{ 0, -769, 992, -2477\}, \{ 0, -905, 665, -2742\},\n\
\{ 0, -944, 665, -2710\}, \{ 0, -1180, 727, -2794\},\n\
\{ 0, -1012, 642, -2599\}, \{ 0, -1195, 690, -2770\},\n\
\{ 0, -1191, 667, -2846\}, \{ 0, -1173, 684, -2759\},\n\
\{ 0, -1158, 708, -2795\}, \{ 0, -1072, 678, -2852\},\n\
\{ 0, -1175, 872, -2747\}, \{ 0, -1011, 862, -2673\},\n\
\{ 0, -1086, 755, -2927\}, \{ 0, -1042, 1076, -2731\},\n\
\{ 0, -1042, 914, -2765\}, \{ 0, -758, 1182, -2443\},\n\
\{ 0, -757, 1219, -2500\}, \{ 0, -534, 1472, -2295\},\n\
\{ 0, -497, 1543, -2104\}, \{ 0, -1267, -632, -3273\},\n\
\{ 0, -1133, -761, -3048\}, \{ 0, -1065, -375, -2952\},\n\
\{ 0, -722, -133, -2551\}, \{ 0, -586, 52, -2505\},\n\
\{ 0, -546, 67, -2219\}, \{ 0, -477, 177, -2017\},\n\
\{ 0, -317, 317, -1888\}, \{ 0, -161, 364, -1712\},\n\
\{ 0, 5, 359, -1770\}, \{ 0, -283, 214, -1901\},\n\
\{ 0, -59, 353, -1551\}, \{ 0, 108, 454, -1465\},\n\
\{ 0, -74, 796, -1225\}, \{ 0, 41, 685, -1221\},\n\
\{ 0, 84, 576, -1318\}, \{ 0, 14, 504, -1313\},\n\
\{ 0, 37, 448, -1301\}, \{ 0, 18, 344, -1408\},\n\
\{ 0, -70, 240, -1384\}, \{ 0, -27, 186, -1595\},\n\
\{ 0, 622, 981, -855\}, \{ 0, 351, 889, -1188\},\n\
\{ 0, 475, 758, -1328\}, \{ 0, 305, 1025, -1222\},\n\
\{ 0, 526, 609, -1397\}, \{ 0, 398, 426, -1695\},\n\
\{ 0, 237, 543, -1835\}, \{ 0, 357, 739, -1747\},\n\
\{ 0, 400, 699, -1834\}, \{ 0, 319, 943, -1998\},\n\
\{ 0, 244, 783, -2197\}, \{ 0, 249, 976, -2195\},\n\
\{ 0, 266, 859, -2406\}, \{ 0, 332, 959, -2477\},\n\
\{ 0, 225, 968, -2554\}, \{ 0, 97, 808, -2815\},\n\
\{ 0, 73, 895, -2852\}, \{ 0, -155, 877, -2986\},\n\
\{ 0, -71, 914, -2943\}, \{ 0, -232, 862, -2966\},\n\
\{ 0, -347, 772, -3176\}, \{ 0, 675, 250, -956\},\n\
\{ 0, 589, 204, -935\}, \{ 0, 459, 110, -867\},\n\
\{ 0, 149, -88, -1251\}, \{ 0, 272, -145, -930\},\n\
\{ 0, 304, -62, -857\}, \{ 0, 24, -487, -1384\},\n\
\{ 0, 51, -31, -984\}, \{ 0, 154, -77, -992\},\n\
\{ 0, -23, -238, -1234\}, \{ 0, 28, -331, -1323\},\n\
\{ 0, 104, -415, -1424\}, \{ 0, -177, -633, -1704\},\n\
\{ 0, 21, -514, -1572\}, \{ 0, 210, -796, -1584\},\n\
\{ 0, 133, -693, -1782\}, \{ 0, 161, -882, -1824\},\n\
\{ 0, 118, -1098, -1994\}, \n\
};"
calMap[LJ03]="\{\n\
\{ 0, 13063, -4747, -10433\}, \{ 0, 3443, -4140, -9849\},\n\
\{ 0, 7069, -4629, -10540\}, \{ 0, 13946, -4544, -10775\},\n\
\{ 0, 12968, -4307, -10347\}, \{ 0, 20281, -5019, -11282\},\n\
\{ 0, 22661, -5079, -11148\}, \{ 0, 16734, -4442, -10374\},\n\
\{ 0, 15423, -4074, -10422\}, \{ 0, 22851, -4441, -10405\},\n\
\{ 0, 14291, -3978, -9960\}, \{ 0, 4367, -3954, -9810\},\n\
\{ 0, 11785, -3957, -10150\}, \{ 0, 3218, -3775, -9825\},\n\
\{ 0, 3344, -3314, -9254\}, \{ 0, 6873, -3528, -9614\},\n\
\{ 0, 3630, -3230, -9069\}, \{ 0, 3442, -3275, -9653\},\n\
\{ 0, 3346, -3858, -9895\}, \{ 0, 3721, -3391, -9296\},\n\
\{ 0, 3261, -3428, -9383\}, \{ 0, -24770, -8031, -10490\},\n\
\{ 0, -24608, -7690, -10198\}, \{ 0, -24868, -7897, -9937\},\n\
\{ 0, -24880, -7994, -10295\}, \{ 0, -24908, -7089, -10312\},\n\
\{ 0, -24547, -7588, -10044\}, \{ 0, -24905, -8076, -9985\},\n\
\{ 0, -24646, -7229, -9709\}, \{ 0, -24916, -7800, -10193\},\n\
\{ 0, -25334, -8019, -10733\}, \{ 0, -24839, -7637, -10037\},\n\
\{ 0, -25020, -7138, -9907\}, \{ 0, -24502, -7503, -10369\},\n\
\{ 0, -24471, -7222, -10546\}, \{ 0, -24537, -7066, -10359\},\n\
\{ 0, -24407, -6616, -9797\}, \{ 0, -23898, -7370, -10755\},\n\
\{ 0, -24587, -7630, -10656\}, \{ 0, -24411, -7258, -11072\},\n\
\{ 0, -24028, -7203, -10471\}, \{ 0, -24139, -7585, -10014\},\n\
\{ 0, -23817, -6456, -10002\}, \{ 0, -24122, -6453, -10354\},\n\
\{ 0, 25236, -6345, -9380\}, \{ 0, 25260, -6144, -9727\},\n\
\{ 0, -25031, -6591, -10264\}, \{ 0, 11624, -6478, -10071\},\n\
\{ 0, 11896, -5407, -9780\}, \{ 0, 14144, -5554, -10328\},\n\
\{ 0, 5556, -5558, -10775\}, \{ 0, 3406, -5945, -10115\},\n\
\{ 0, 3384, -5384, -10050\}, \{ 0, 3263, -4468, -9634\},\n\
\{ 0, 5991, -4734, -9494\}, \{ 0, 3953, -5377, -10430\},\n\
\{ 0, 4514, -3687, -9547\}, \{ 0, 4487, -3691, -9332\},\n\
\{ 0, 5085, -4417, -9657\}, \{ 0, 5222, -3694, -9115\},\n\
\{ 0, 4960, -4086, -8862\}, \{ 0, 4994, -4292, -9127\},\n\
\{ 0, 5162, -4509, -8554\}, \{ 0, 4337, -5390, -8443\},\n\
\{ 0, 4628, -4976, -9047\}, \{ 0, 4293, -4876, -9218\},\n\
\{ 0, 4465, -5352, -9014\}, \{ 0, 4428, -4936, -9521\},\n\
\{ 0, 4048, -5497, -9795\}, \{ 0, 4290, -6034, -9032\},\n\
\{ 0, 4184, -4996, -8434\}, \{ 0, 3950, -4983, -8474\},\n\
\{ 0, 4247, -4407, -7955\}, \{ 0, 4386, -4769, -8079\},\n\
\{ 0, 4311, -5367, -8478\}, \{ 0, 4283, -4809, -8025\},\n\
\{ 0, 3885, -4011, -7495\}, \{ 0, 3885, -4593, -7577\},\n\
\{ 0, 3622, -5239, -8157\}, \{ 0, 3576, -5007, -7816\},\n\
\{ 0, 3778, -3793, -7362\}, \n\
};"
calMap[LJ04]="\{\n\
\{ 0, -3188, -5668, -7029\}, \{ 0, -3144, -5592, -6708\},\n\
\{ 0, -3332, -5859, -7135\}, \{ 0, -3402, -5694, -6908\},\n\
\{ 0, -3376, -5858, -7070\}, \{ 0, -3383, -5474, -6886\},\n\
\{ 0, -3518, -5487, -6925\}, \{ 0, -3383, -5342, -6659\},\n\
\{ 0, -3487, -5535, -6848\}, \{ 0, -3472, -5206, -6576\},\n\
\{ 0, -3432, -5335, -6581\}, \{ 0, -3502, -5071, -6421\},\n\
\{ 0, -3549, -5020, -6390\}, \{ 0, -3618, -4961, -6310\},\n\
\{ 0, -3774, -4938, -6377\}, \{ 0, -3868, -5039, -6488\},\n\
\{ 0, -3865, -4778, -6328\}, \{ 0, -3812, -4602, -6360\},\n\
\{ 0, -3990, -4498, -6189\}, \{ 0, -3820, -4493, -6070\},\n\
\{ 0, -3793, -4262, -5963\}, \{ 0, -4355, -5745, -6648\},\n\
\{ 0, -4372, -5742, -6633\}, \{ 0, -4458, -5618, -6650\},\n\
\{ 0, -4484, -5695, -6732\}, \{ 0, -4367, -5513, -6642\},\n\
\{ 0, -4433, -5498, -6628\}, \{ 0, -4364, -5480, -6563\},\n\
\{ 0, -4344, -5382, -6497\}, \{ 0, -4255, -5470, -6465\},\n\
\{ 0, -4154, -5145, -6183\}, \{ 0, -4211, -5200, -6136\},\n\
\{ 0, -4086, -5205, -6195\}, \{ 0, -4113, -5261, -6338\},\n\
\{ 0, -4069, -4832, -5831\}, \{ 0, -3835, -4826, -5801\},\n\
\{ 0, -4030, -5011, -6065\}, \{ 0, -3711, -4838, -5795\},\n\
\{ 0, -3644, -4881, -5899\}, \{ 0, -3507, -4813, -5800\},\n\
\{ 0, -3453, -4947, -5520\}, \{ 0, -3374, -4954, -5642\},\n\
\{ 0, -4837, -5736, -7500\}, \{ 0, -4470, -5620, -7385\},\n\
\{ 0, -4401, -5408, -7370\}, \{ 0, -4271, -5626, -7496\},\n\
\{ 0, -4286, -5828, -7556\}, \{ 0, -4184, -5982, -7565\},\n\
\{ 0, -3923, -5491, -7415\}, \{ 0, -3926, -5554, -7685\},\n\
\{ 0, -3657, -5235, -7542\}, \{ 0, -3530, -5104, -7717\},\n\
\{ 0, -3370, -4853, -7737\}, \{ 0, -3224, -4703, -7679\},\n\
\{ 0, -3100, -4620, -7733\}, \{ 0, -3010, -4547, -7648\},\n\
\{ 0, -2838, -4318, -7619\}, \{ 0, -2907, -4260, -7604\},\n\
\{ 0, -2883, -4306, -7768\}, \{ 0, -2878, -3949, -7601\},\n\
\{ 0, -2927, -4097, -7840\}, \{ 0, -2816, -3790, -7544\},\n\
\{ 0, -2853, -3654, -7534\}, \{ 0, -2052, -2142, -3986\},\n\
\{ 0, -2109, -2259, -4027\}, \{ 0, -2132, -2002, -3745\},\n\
\{ 0, -2275, -2181, -3810\}, \{ 0, -2353, -1951, -3419\},\n\
\{ 0, -2428, -2046, -3391\}, \{ 0, -2537, -1974, -3301\},\n\
\{ 0, -2568, -1805, -3074\}, \{ 0, -2764, -1930, -3068\},\n\
\{ 0, -2793, -1922, -2816\}, \{ 0, -2931, -2060, -2982\},\n\
\{ 0, -3118, -2158, -2858\}, \{ 0, -3370, -2240, -3088\},\n\
\{ 0, -3411, -2369, -3055\}, \{ 0, -3867, -2590, -3016\},\n\
\{ 0, -3965, -2696, -3099\}, \{ 0, -4112, -2907, -3438\},\n\
\{ 0, -4226, -2747, -3341\}, \n\
};"
calMap[LJ06]="\{\n\
\{ 0, -4989, -7102, -2178\}, \{ 0, -5092, -7204, -2325\},\n\
\{ 0, -4959, -7013, -2137\}, \{ 0, -4960, -6784, -1920\},\n\
\{ 0, -5025, -6734, -2104\}, \{ 0, -5181, -6637, -2017\},\n\
\{ 0, -5262, -6792, -2110\}, \{ 0, -5362, -6621, -2110\},\n\
\{ 0, -5258, -6451, -2031\}, \{ 0, -5375, -6390, -2064\},\n\
\{ 0, -5280, -6288, -2052\}, \{ 0, -5445, -6434, -2101\},\n\
\{ 0, -5553, -6402, -2272\}, \{ 0, -5603, -6628, -2477\},\n\
\{ 0, -5661, -6626, -2492\}, \{ 0, -5731, -6618, -2616\},\n\
\{ 0, -5746, -6626, -2664\}, \{ 0, -6007, -7024, -2951\},\n\
\{ 0, -6018, -7010, -2969\}, \{ 0, -5746, -6939, -2833\},\n\
\{ 0, -5770, -7034, -3026\}, \{ 0, -8509, -8777, -6863\},\n\
\{ 0, -8593, -9060, -6868\}, \{ 0, -8514, -9104, -6795\},\n\
\{ 0, -8401, -9387, -6931\}, \{ 0, -8236, -9191, -6586\},\n\
\{ 0, -8155, -9371, -6595\}, \{ 0, -8192, -9551, -6363\},\n\
\{ 0, -7995, -9550, -6185\}, \{ 0, -7968, -9690, -6220\},\n\
\{ 0, -7826, -9694, -6052\}, \{ 0, -7694, -9660, -5763\},\n\
\{ 0, -7857, -10020, -5947\}, \{ 0, -7543, -9682, -5463\},\n\
\{ 0, -7184, -9071, -4747\}, \{ 0, -7282, -9220, -4767\},\n\
\{ 0, -7417, -9371, -4765\}, \{ 0, -7238, -9321, -4430\},\n\
\{ 0, -7320, -9420, -4560\}, \{ 0, -7254, -9185, -4270\},\n\
\{ 0, -7378, -9262, -4324\}, \{ 0, -7078, -9074, -3976\},\n\
\{ 0, -10047, -10956, -7258\}, \{ 0, -10107, -10961, -7192\},\n\
\{ 0, -10264, -11167, -7427\}, \{ 0, -10160, -10823, -7282\},\n\
\{ 0, -10276, -11378, -7508\}, \{ 0, -10576, -11282, -7688\},\n\
\{ 0, -10801, -11460, -7845\}, \{ 0, -10822, -10983, -7809\},\n\
\{ 0, -10947, -10998, -8018\}, \{ 0, -11215, -10876, -8255\},\n\
\{ 0, -11247, -10590, -8188\}, \{ 0, -11302, -10269, -8237\},\n\
\{ 0, -11583, -10213, -8413\}, \{ 0, -11561, -10001, -8448\},\n\
\{ 0, -11482, -9425, -8273\}, \{ 0, -11573, -9203, -8344\},\n\
\{ 0, -11661, -8895, -8267\}, \{ 0, -11843, -8879, -8259\},\n\
\{ 0, -11799, -8715, -8112\}, \{ 0, -12002, -8422, -8238\},\n\
\{ 0, -12022, -8434, -8409\}, \{ 0, -8755, -4274, -4932\},\n\
\{ 0, -9183, -4523, -5458\}, \{ 0, -9293, -4300, -5260\},\n\
\{ 0, -9530, -4543, -5569\}, \{ 0, -9573, -4168, -5429\},\n\
\{ 0, -9847, -4448, -5638\}, \{ 0, -9999, -4504, -5969\},\n\
\{ 0, -9858, -4176, -5716\}, \{ 0, -9988, -4378, -5978\},\n\
\{ 0, -9760, -3942, -5627\}, \{ 0, -10072, -4163, -6002\},\n\
\{ 0, -9892, -4091, -5833\}, \{ 0, -9873, -3867, -5828\},\n\
\{ 0, -9911, -4149, -5877\}, \{ 0, -9844, -4016, -5908\},\n\
\{ 0, -9528, -3912, -5604\}, \{ 0, -9432, -3911, -5648\},\n\
\{ 0, -9314, -3730, -5422\}, \n\
};"
+40
View File
@@ -0,0 +1,40 @@
clear;clc;
fid = fopen("../caldata", "w");
fprintf(fid, "declare -A calMap\n");
for i = 1:6
id = sprintf("JG%02d", i);
write_data(fid, pwd, id);
end
for i = 1:6
id = sprintf("LJ%02d", i);
write_data(fid, pwd, id);
end
fclose(fid);
function write_data(fid, folder_name, dev_id)
file_path = sprintf("%s/phase_%s.mat", folder_name, dev_id);
if ~isfile(file_path)
warning('[%s] dose not exist.\n', file_path);
return;
end
load(file_path);
data = sortrows(dataDec1, 1);
fprintf(fid, 'calMap[%s]="\\{\\n\\\n', dev_id);
for i = 1:size(data,1)
if (mod(i, 2) == 1)
fprintf(fid, "\t");
end
fprintf(fid, "\\{%6d, %6d, %6d, %6d\\},", ...
data(i,2), data(i,3), data(i,4), data(i,5));
if (mod(i, 2) == 1)
fprintf(fid, " ");
else
fprintf(fid, "\\n\\\n");
end
end
fprintf(fid, '\\n\\\n};"\n\n');
end
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+442
View File
@@ -0,0 +1,442 @@
'''
@brief This is an example plugin, can receive and send data
@author
@date
@license LGPL-3.0
'''
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QTextEdit, QPushButton, QLabel, QScrollArea, QSplitter
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtGui import QFont, QTextCursor
from struct import Struct
try:
import utils_ui
from plugins.base import Plugin_Base
from conn import ConnectionStatus
from i18n import _
from widgets import statusBar
except ImportError:
from COMTool import utils_ui
from COMTool.plugins.base import Plugin_Base
from COMTool.i18n import _
from COMTool.conn import ConnectionStatus
from COMTool.widgets import statusBar
class Plugin(Plugin_Base):
id = "DUIFEI"
name = _("DUIFEI")
showReceiveDataSignal = pyqtSignal(str)
def onInit(self, config):
'''
init params
'''
default = {
"version": 1,
"customSendItems": [
{
"caption": "自检",
"icon": "fa5.question-circle",
"data": "5A 54 E1 DD 00 BE 02 5A FE"
},
# {
# "caption": "数据发送测试 - 1",
# "icon": "fa5.play-circle",
# "data": ""
# },
# {
# "caption": "数据发送测试 - 2",
# "icon": "fa5.play-circle",
# "data": ""
# },
{
"caption": "装订 - 【主】反拦截小功率",
"icon": "fa5.play-circle",
"data": "5A 54 E3 DD 77 11 00 00 00 48 06 5A FE"
},
{
"caption": "装订 - 【主】反拦截全功率",
"icon": "fa5.play-circle",
"data": "5A 54 E3 DD 66 11 00 00 00 37 06 5A FE"
},
{
"caption": "装订 - 【主】反拦截静默",
"icon": "fa5.play-circle",
"data": "5A 54 E3 DD 88 11 00 00 00 59 06 5A FE"
},
{
"caption": "遥测 - 【主】反拦截",
"icon": "fa5.play-circle",
"data": "5A 54 E6 DD 99 00 5C 03 5A FE"
},
{
"caption": "点名 - 【主】反拦截",
"icon": "fa5.play-circle",
"data": "5A 54 E5 DD 77 00 39 03 5A FE"
},
{
"caption": "装订 - 【从】拦截小功率",
"icon": "fa5.play-circle",
"data": "5A 54 E3 DD 77 00 00 00 00 37 06 5A FE"
},
{
"caption": "装订 - 【从】拦截大功率",
"icon": "fa5.play-circle",
"data": "5A 54 E3 DD 66 00 00 00 00 26 06 5A FE"
},
{
"caption": "装订 - 【从】拦截静默",
"icon": "fa5.play-circle",
"data": "5A 54 E3 DD 88 00 00 00 00 48 06 5A FE"
},
{
"caption": "遥测 - 【从】拦截",
"icon": "fa5.play-circle",
"data": "5A 54 F6 DD 99 00 6C 03 5A FE"
},
{
"caption": "点名 - 【从】拦截",
"icon": "fa5.play-circle",
"data": "5A 54 F5 DD 77 00 49 03 5A FE"
}
]
}
self.config = config
for k in default:
if not k in self.config:
self.config[k] = default[k]
def onConnChanged(self, status:ConnectionStatus, msg:str):
print("-- connection changed: {}, msg: {}".format(status, msg))
def onWidgetMain(self, parent):
'''
main widget, just return a QWidget object
'''
self.mainWidget = QSplitter(Qt.Vertical)
# receive widget
self.receiveWidget = QTextEdit("")
font = QFont('Consolas, DejaVu Sans Mono, Courier New, monospace, Microsoft YaHei', 10)
self.receiveWidget.setFont(font)
self.receiveWidget.setLineWrapMode(QTextEdit.NoWrap)
# clear button
self.clearBtn = QPushButton("")
utils_ui.setButtonIcon(self.clearBtn, "mdi6.broom")
# send scroll
self.customSendScroll = QScrollArea()
self.customSendScroll.setMinimumHeight(20)
self.customSendScroll.setWidgetResizable(True)
self.customSendScroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.customSendScroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
cutomSendItemsWraper = QWidget()
self.customSendScroll.setWidget(cutomSendItemsWraper)
# -- wrapper widget
cutomSendItemsWraper0 = QWidget()
cutomSendItemsWraper0.setProperty("class", "scrollbar2")
layout0 = QVBoxLayout()
layout0.setContentsMargins(0,8,0,0)
cutomSendItemsWraper0.setLayout(layout0)
layout0.addWidget(self.customSendScroll)
customSendItemsLayoutWrapper = QVBoxLayout()
customSendItemsLayoutWrapper.setContentsMargins(0,0,0,0)
cutomSendItemsWraper.setLayout(customSendItemsLayoutWrapper)
# -- items container
self.customItems = QWidget()
self.customSendItemsLayout = QVBoxLayout()
self.customSendItemsLayout.setContentsMargins(0,0,0,0)
self.customItems.setLayout(self.customSendItemsLayout)
customSendItemsLayoutWrapper.addWidget(self.customItems)
customSendItemsLayoutWrapper.addStretch(0)
# add widgets
self.mainWidget.addWidget(self.receiveWidget)
self.mainWidget.addWidget(self.clearBtn)
self.mainWidget.addWidget(cutomSendItemsWraper0)
self.mainWidget.setStretchFactor(0, 2)
self.mainWidget.setStretchFactor(1, 1)
self.mainWidget.setStretchFactor(2, 11)
# event
def clearReceived():
self.receiveWidget.clear();self.statusBar.clear()
self.clearBtn.clicked.connect(clearReceived)
return self.mainWidget
def onWidgetStatusBar(self, parent):
self.statusBar = statusBar(rxTxCount=True)
return self.statusBar
def onUiInitDone(self):
'''
UI init done, you can update your widget here
this method runs in UI thread, do not block too long
'''
newItems = []
print(self.config["customSendItems"])
for item in self.config["customSendItems"]:
print(item)
item = self.insertSendItem(item, load=True)
newItems.append(item)
self.config["customSendItems"] = newItems
self.showReceiveDataSignal.connect(self.showReceivedData)
# frame struct
self.structSelfTestRsp = Struct("<BB B BBBbbb BbBBB BB")
self.structStatusCheckRsp = Struct("<BB Q HIII IBBBBI BBHH HHHIIIIII i II 4s IIII d Q dBB dB H B 3s BBBbbb BbBBB 2s")
self.structFljData = Struct("<dddd IHI fff fff")
self.structLjData = Struct("<IHI ffff IHI fff fff fff IHI fff fff fff IHI fff fff fff I")
self.structSysInfo = Struct("<IHI H B I B fff fff fff")
def insertSendItem(self, item = None, load = False):
caption = item["caption"]
itemWidget = QWidget()
layout = QHBoxLayout()
layout.setContentsMargins(0,0,0,0)
itemWidget.setLayout(layout)
send = QPushButton("")
label = QLabel(caption)
if (not "icon" in item) or not item["icon"]:
item["icon"] = "fa.send"
utils_ui.setButtonIcon(send, item["icon"])
send.setProperty("class", "smallBtn")
def sendCustomData(idx):
self.sendCustomItem(self.config["customSendItems"][idx])
send.clicked.connect(lambda: sendCustomData(self.customSendItemsLayout.indexOf(itemWidget)))
layout.addWidget(label)
layout.addWidget(send)
self.customSendItemsLayout.addWidget(itemWidget)
if not load:
self.config["customSendItems"].append(item)
return item
def showReceivedData(self, text: str):
curScrollValue = self.receiveWidget.verticalScrollBar().value()
self.receiveWidget.moveCursor(QTextCursor.End)
endScrollValue = self.receiveWidget.verticalScrollBar().value()
self.receiveWidget.insertPlainText(text)
if curScrollValue < endScrollValue:
self.receiveWidget.verticalScrollBar().setValue(curScrollValue)
else:
self.receiveWidget.moveCursor(QTextCursor.End)
def onReceived(self, data : bytes):
'''
call in receive thread, not UI thread
'''
self.statusBar.addRx(len(data))
## Apply data validation check
if len(data) < 7:
self.showReceiveDataSignal.emit("\n### Wrong data format: wrong frame header/tail\n")
return
dataLen = data[-3]
if data[0] != 0x5A or data[1] != 0x54 or data[-1] != 0xFE or data[-2] != 0x5A:
self.showReceiveDataSignal.emit("\n### Wrong data format: wrong length\n")
checkSum = 0
for i in data[2:-4]:
checkSum += i
if checkSum & 0xFF != data[-4]:
self.showReceiveDataSignal.emit("\n### Wrong data format: wrong check sum\n")
## Eval data
data = data[2:-5].replace(b'\x00\x54\xFE', b'\x54\xFE')
# self.printFrame(data)
if data[0] == 0xE1:
# eval self test
self.showReceiveDataSignal.emit(self.evalSelfTestRsp(data) + "\n")
elif data[0] == 0xE6 or data[0] == 0xF6:
self.showReceiveDataSignal.emit(self.evalStatusCheckRsp(data) + "\n")
elif data[0] == 0xE5 or data[0] == 0xF5:
self.showReceiveDataSignal.emit('Retrieved Data Frame:\n' + self.printFrame(data) + "\n")
else:
self.showReceiveDataSignal.emit(f"\n### Unexpected response code 0x{data[0]:02x}.\n")
def evalSelfTestRsp(self, data: bytes):
try:
payload = self.structSelfTestRsp.unpack(data)
except :
return f"\n### evalSelfTestRsp:: Failed to unpack data (data length {len(data)} byte).\n"
ret = "----------- 自检回令 -----------\n"
ret += f"节点编号: 0x{payload[-2]:02X}\n"
ret += "节点类型: "
if payload[1] == 0xDD:
ret += f"K频段 (0x{payload[1]:02X})\n"
elif payload[1] == 0xEE:
ret += f"S频段 (0x{payload[1]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[1]:02X})\n"
ret += "自检结果: "
if payload[2] == 0xAA:
ret += f"正常 (0x{payload[2]:02X})\n"
elif payload[2] == 0x55:
ret += f"异常 (0x{payload[2]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[2]:02X})\n"
hwOffset = 3
ret += f"FPGA 电压监测: {bin(payload[hwOffset+0])[2:].zfill(8)}\n"
ret += f"时钟锁定状态: {bin(payload[hwOffset+1])[2:].zfill(8)}\n"
ret += f"AD 锁定状态: {bin(payload[hwOffset+2])[2:].zfill(8)}\n"
ret += f"AD 温度 1: {payload[hwOffset+3]:>4d}\n"
ret += f"AD 温度 2: {payload[hwOffset+4]:>4d}\n"
ret += f"FPGA 温度: {payload[hwOffset+5]:>4d}\n"
ret += f"电压监测: {bin(payload[hwOffset+6])[2:].zfill(8)}\n"
ret += f"射频温度: {payload[hwOffset+7]:>4d}\n"
ret += f"锁定指示: {bin(payload[hwOffset+8])[2:].zfill(8)}\n"
ret += f"MGC 1~2: {payload[hwOffset+9] & 0x0f:>2d} - {payload[hwOffset+9] >> 4:>2d}\n"
ret += f"MGC 3~4: {payload[hwOffset+10] & 0x0f:>2d} - {payload[hwOffset+10] >> 4:>2d}\n"
ret += "--------------------------------\n"
return ret + '\n' + self.printFrame(data)
def printFrame(self, data: bytes):
ret = ''
for i in range(len(data)):
ret += f'{data[i]:02X}'
ret += '\n' if i%16 == 15 else ' '
ret += '\n'
return ret
def evalStatusCheckRsp(self, data: bytes):
try:
payload = self.structStatusCheckRsp.unpack(data)
except :
return f"\n### evalStatusCheckRsp:: Failed to unpack data (data length {len(data)} byte).\n"
ret = "----------- 遥测回令 -----------\n"
ret += "节点类型: "
if payload[1] == 0xDD:
ret += f"K频段 (0x{payload[1]:02X})\n"
elif payload[1] == 0xEE:
ret += f"S频段 (0x{payload[1]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[1]:02X})\n"
ret += f"时间戳: {payload[2]/1e5:.2f} ms\n"
sysbusOffset = 3
linkOffset = 7
phyOffset = 30
hwOffset = 44
ret += "\n -- 总线状态\n"
ret += f"配置装订: {payload[sysbusOffset + 0]:04X}\n"
ret += f"装置点名计数: {payload[sysbusOffset + 1]:>6d}\n"
ret += f"业务下发计数: {payload[sysbusOffset + 2]:>6d}\n"
ret += f"遥测请求计数: {payload[sysbusOffset + 3]:>6d}\n"
ret += "\n -- 链路层状态\n"
ret += f"帧号: {payload[linkOffset + 0]:>6d}\n"
ret += f"时隙号: {payload[linkOffset + 1]:>3d}\n"
ret += "当前角色: "
if payload[linkOffset + 2] == 0xAA:
ret += f"反拦截 (0x{payload[linkOffset + 2]:02X})\n"
elif payload[linkOffset + 2] == 0xCC:
ret += f"拦截 (0x{payload[linkOffset + 2]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[linkOffset + 2]:02X})\n"
ret += "网络连接状态: "
if payload[linkOffset + 3] == 0x11:
ret += f"已连接 (0x{payload[linkOffset + 3]:02X})\n"
elif payload[linkOffset + 3] == 0x00:
ret += f"未连接 (0x{payload[linkOffset + 3]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[linkOffset + 3]:02X})\n"
ret += "网络运行阶段: "
if payload[linkOffset + 4] == 0x11:
ret += f"扫描建网 (0x{payload[linkOffset + 4]:02X})\n"
elif payload[linkOffset + 4] == 0x22:
ret += f"业务通信 (0x{payload[linkOffset + 4]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[linkOffset + 4]:02X})\n"
ret += f"重建/入网计数: {payload[linkOffset + 5]:>6d}\n"
ret += f"通信波位号: {payload[linkOffset + 6]:>2d}\n"
ret += "通信波束宽度: "
if payload[linkOffset + 7] == 0x01:
ret += f"120° 宽波束 (0x{payload[linkOffset + 7]:02X})\n"
elif payload[linkOffset + 7] == 0x02:
ret += f"60° 次波束 (0x{payload[linkOffset + 7]:02X})\n"
elif payload[linkOffset + 7] == 0x03:
ret += f"25° 次波束 (0x{payload[linkOffset + 7]:02X})\n"
elif payload[linkOffset + 7] == 0x04:
ret += f"8° 窄波束 (0x{payload[linkOffset + 7]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[linkOffset + 7]:02X})\n"
ret += f"离轴角: {payload[linkOffset + 8]*0.1:.2f}°\n"
ret += f"偏航角: {payload[linkOffset + 9]*0.1:.2f}°\n"
ret += f"基准帧发送计数: {payload[linkOffset + 10]:>6d}\n"
ret += f"基准帧接收计数: {payload[linkOffset + 11]:>6d}\n"
ret += f"基准帧正确计数: {payload[linkOffset + 12]:>6d}\n"
ret += f"双向握手帧发送计数: {payload[linkOffset + 13]:>6d}\n"
ret += f"双向握手帧接收计数: {payload[linkOffset + 14]:>6d}\n"
ret += f"双向握手帧正确计数: {payload[linkOffset + 15]:>6d}\n"
ret += f"业务帧发送计数: {payload[linkOffset + 16]:>6d}\n"
ret += f"业务帧接收计数: {payload[linkOffset + 17]:>6d}\n"
ret += f"业务帧正确计数: {payload[linkOffset + 18]:>6d}\n"
ret += f"时间偏差记录: {payload[linkOffset + 19]/1e2:.2f} us\n"
ret += f"发送数据 ID: {payload[linkOffset + 20]:>6d}\n"
ret += f"接收数据 ID: {payload[linkOffset + 21]:>6d}\n"
ret += "\n -- 物理层状态\n"
ret += f"捕获计数: {payload[phyOffset + 0]:>6d}\n"
ret += f"帧同步计数: {payload[phyOffset + 1]:>6d}\n"
ret += f"译码计数: {payload[phyOffset + 2]:>6d}\n"
ret += f"CRC 正确计数:{payload[phyOffset + 3]:>6d}\n"
ret += f"多普勒估计: {payload[phyOffset + 4]:.2f} Hz\n"
ret += f"正确接收时刻: {payload[phyOffset + 5]/1e2:.2f} us\n"
ret += f"捕获峰均比: {payload[phyOffset + 6]:.2f}\n"
ret += f"捕获相位值: {payload[phyOffset + 7]:>3d}\n"
ret += f"捕获频偏通道: {payload[phyOffset + 8]:>3d}\n"
ret += f"帧同步峰均比: {payload[phyOffset + 9]:.2f}\n"
ret += f"帧同步频偏通道: {payload[phyOffset + 10]:>3d}\n"
ret += f"交织输入数据幅度统计:\t0x{payload[phyOffset + 11]:04X}\n"
ret += "天线工作模式: "
if payload[phyOffset + 12] == 0x01:
ret += f"静默模式 (0x{payload[phyOffset + 12]:02X})\n"
elif payload[phyOffset + 12] == 0x02:
ret += f"低功率模式 (0x{payload[phyOffset + 12]:02X})\n"
elif payload[phyOffset + 12] == 0x03:
ret += f"全功率模式 (0x{payload[phyOffset + 12]:02X})\n"
else:
ret += f"【未知错误】(0x{payload[phyOffset + 12]:02X})\n"
ret += "\n -- 硬件状态\n"
ret += f"FPGA 电压监测: {bin(payload[hwOffset+0])[2:].zfill(8)}\n"
ret += f"时钟锁定状态: {bin(payload[hwOffset+1])[2:].zfill(8)}\n"
ret += f"AD 锁定状态: {bin(payload[hwOffset+2])[2:].zfill(8)}\n"
ret += f"AD 温度 1: {payload[hwOffset+3]:>4d}\n"
ret += f"AD 温度 2: {payload[hwOffset+4]:>4d}\n"
ret += f"FPGA 温度: {payload[hwOffset+5]:>4d}\n"
ret += f"电压监测: {bin(payload[hwOffset+6])[2:].zfill(8)}\n"
ret += f"射频温度: {payload[hwOffset+7]:>4d}\n"
ret += f"锁定指示: {bin(payload[hwOffset+8])[2:].zfill(8)}\n"
ret += f"MGC 1~2: {payload[hwOffset+9] & 0x0f:>2d} - {payload[hwOffset+9] >> 4:>2d}\n"
ret += f"MGC 3~4: {payload[hwOffset+10] & 0x0f:>2d} - {payload[hwOffset+10] >> 4:>2d}\n"
ret += "--------------------------------\n"
return ret + '\n' + self.printFrame(data)
def onSent(self, ok, msg, length, path):
if ok:
self.statusBar.addTx(length)
else:
self.hintSignal.emit("error", _("Error"), _("Send data failed!") + " " + msg)
def sendCustomItem(self, item):
data = item["data"]
dateBytes = self.parseSendData(data, encoding = self.configGlobal["encoding"], isHexStr = True)
if dateBytes:
self.send(dateBytes, callback=self.onSent)
@@ -359,20 +359,20 @@
/* Definitions for driver GPIO */
#define XPAR_XGPIO_NUM_INSTANCES 1
/* Definitions for peripheral CONFIG_GPIO */
#define XPAR_CONFIG_GPIO_BASEADDR 0x41200000
#define XPAR_CONFIG_GPIO_HIGHADDR 0x4120FFFF
#define XPAR_CONFIG_GPIO_DEVICE_ID 0
#define XPAR_CONFIG_GPIO_INTERRUPT_PRESENT 0
#define XPAR_CONFIG_GPIO_IS_DUAL 1
/* Definitions for peripheral MPC_GPIO */
#define XPAR_MPC_GPIO_BASEADDR 0x41200000
#define XPAR_MPC_GPIO_HIGHADDR 0x4120FFFF
#define XPAR_MPC_GPIO_DEVICE_ID 0
#define XPAR_MPC_GPIO_INTERRUPT_PRESENT 0
#define XPAR_MPC_GPIO_IS_DUAL 1
/******************************************************************/
/* Canonical definitions for peripheral CONFIG_GPIO */
/* Canonical definitions for peripheral MPC_GPIO */
#define XPAR_GPIO_0_BASEADDR 0x41200000
#define XPAR_GPIO_0_HIGHADDR 0x4120FFFF
#define XPAR_GPIO_0_DEVICE_ID XPAR_CONFIG_GPIO_DEVICE_ID
#define XPAR_GPIO_0_DEVICE_ID XPAR_MPC_GPIO_DEVICE_ID
#define XPAR_GPIO_0_INTERRUPT_PRESENT 0
#define XPAR_GPIO_0_IS_DUAL 1
@@ -425,17 +425,14 @@
/* Definitions for Fabric interrupts connected to ps7_scugic_0 */
#define XPAR_FABRIC_PHY_IRQ_INTR 61U
#define XPAR_FABRIC_FRAME_UART_0_RX_INTR_INTR 62U
#define XPAR_FABRIC_FRAME_UART_0_TX_INTR_INTR 63U
#define XPAR_FABRIC_MPC_IRQ_INTR 64U
#define XPAR_FABRIC_PHY_5MS_INTR 65U
#define XPAR_FABRIC_PHY_5MS_DELAY_2MS_INTR 66U
#define XPAR_FABRIC_PHY_5MS_INTR 62U
#define XPAR_FABRIC_PHY_5MS_DELAY_2MS_INTR 63U
#define XPAR_FABRIC_MPC_RX_IRQ_INTR 64U
#define XPAR_FABRIC_MPC_TX_IRQ_INTR 65U
/******************************************************************/
/* Canonical definitions for Fabric interrupts connected to ps7_scugic_0 */
#define XPAR_FABRIC_FRAME_UART_0_RX_INTR_VEC_ID XPAR_FABRIC_FRAME_UART_0_RX_INTR_INTR
#define XPAR_FABRIC_FRAME_UART_0_TX_INTR_VEC_ID XPAR_FABRIC_FRAME_UART_0_TX_INTR_INTR
/******************************************************************/
@@ -43,10 +43,10 @@
XGpio_Config XGpio_ConfigTable[XPAR_XGPIO_NUM_INSTANCES] =
{
{
XPAR_CONFIG_GPIO_DEVICE_ID,
XPAR_CONFIG_GPIO_BASEADDR,
XPAR_CONFIG_GPIO_INTERRUPT_PRESENT,
XPAR_CONFIG_GPIO_IS_DUAL
XPAR_MPC_GPIO_DEVICE_ID,
XPAR_MPC_GPIO_BASEADDR,
XPAR_MPC_GPIO_INTERRUPT_PRESENT,
XPAR_MPC_GPIO_IS_DUAL
}
};
+6 -12
View File
@@ -18,18 +18,6 @@ BEGIN PROCESSOR
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = frame_uart
PARAMETER DRIVER_VER = 1.0
PARAMETER HW_INSTANCE = Frame_Uart_0
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = gpio
PARAMETER DRIVER_VER = 4.4
PARAMETER HW_INSTANCE = config_gpio
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 2.0
@@ -54,6 +42,12 @@ BEGIN DRIVER
PARAMETER HW_INSTANCE = mpc_bram_interface_mpc_bram_ctrl
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = gpio
PARAMETER DRIVER_VER = 4.4
PARAMETER HW_INSTANCE = mpc_gpio
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = bram
PARAMETER DRIVER_VER = 4.3
+1 -1
View File
@@ -13,7 +13,7 @@ RM := rm -rf
-include sources.mk
-include src/util/subdir.mk
-include src/time_ctrl/subdir.mk
-include src/systembus/subdir.mk
-include src/mpc/subdir.mk
-include src/networking/phy_layer/subdir.mk
-include src/networking/link_layer/geometry/subdir.mk
-include src/networking/link_layer/subdir.mk
@@ -23,7 +23,7 @@ C_DEPS += \
src/dev_profile/%.o: ../src/dev_profile/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
@@ -4,23 +4,23 @@
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/systembus/systembus.c \
../src/systembus/systembus_uart.c
../src/mpc/mpc.c \
../src/mpc/mpc_hw.c
OBJS += \
./src/systembus/systembus.o \
./src/systembus/systembus_uart.o
./src/mpc/mpc.o \
./src/mpc/mpc_hw.o
C_DEPS += \
./src/systembus/systembus.d \
./src/systembus/systembus_uart.d
./src/mpc/mpc.d \
./src/mpc/mpc_hw.d
# Each subdirectory must supply rules for building sources it contributes
src/systembus/%.o: ../src/systembus/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
@@ -23,7 +23,7 @@ C_DEPS += \
src/networking/link_layer/geometry/%.o: ../src/networking/link_layer/geometry/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
@@ -38,7 +38,7 @@ C_DEPS += \
src/networking/link_layer/%.o: ../src/networking/link_layer/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
@@ -20,7 +20,7 @@ C_DEPS += \
src/networking/phy_layer/%.o: ../src/networking/phy_layer/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
+1 -1
View File
@@ -23,7 +23,7 @@ C_DEPS += \
src/%.o: ../src/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
+1 -1
View File
@@ -17,7 +17,7 @@ C_DEPS += \
src/time_ctrl/%.o: ../src/time_ctrl/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
+1 -1
View File
@@ -32,7 +32,7 @@ C_DEPS += \
src/util/%.o: ../src/util/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
+6 -6
View File
@@ -35,6 +35,8 @@
// 2 - print warnings and errors
// 1 - print only errors
// other - print nothing
#define APP_EMULATE_DATA
#define DATALINK_ENABLE_AUTORECONNECT
#define DATALINK_ENABLE_AUTOTIMESYNC
//#define DATALINK_ENABLE_BERTEST
@@ -71,9 +73,10 @@
#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
#define MPC_BRAM_ID XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_DEVICE_ID
#define MPC_GPIO_ID XPAR_MPC_GPIO_DEVICE_ID
#define MPC_TX_INTR_ID XPAR_FABRIC_MPC_TX_IRQ_INTR
#define MPC_RX_INTR_ID XPAR_FABRIC_MPC_RX_IRQ_INTR
// Global Timer config
#define GLOBAL_TIMER_DEVICE_ID XPAR_GLOBAL_TMR_DEVICE_ID
@@ -93,9 +96,6 @@
#if !defined(DATALINK_ENABLE_AUTOTIMESYNC)
#warning To enbale bit error rate test, auto time-sync should be enabled...
#endif
#if defined(DATALINK_ENABLE_AUTORECONNECT)
#error Do not support auto reconnnect in bit error rate test mode...
#endif
#endif
#endif
@@ -11,7 +11,7 @@ struct xil_timer_init_param xil_scutimer_init_param = {
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
.ticks_count = (SCU_TIMER_CLK_HZ/2), //update log every 500ms
.platform_ops = &xil_timer_ops,
.extra = &xil_scutimer_init_param
};
+196 -157
View File
@@ -1,5 +1,4 @@
/***************************************************************************//**
* @file ad9371/src/app/headless.c
/******************************************************************************* * @file ad9371/src/app/headless.c
* @brief Implementation of Main Function.
********************************************************************************
* Copyright 2017(c) Analog Devices, Inc.
@@ -66,7 +65,8 @@ int HARDWARE_initialize()
Status = HARDWARE_ad9371Config();
if (Status != ADIERR_OK){
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
@@ -75,11 +75,11 @@ int HARDWARE_initialize()
// /**********************************************************/
// Status = HW_ad9371DynamicCfgInit();
// if (Status != ADIERR_OK){
// printf("HW:: AD9371 dynamic configuration initialization failed!\n");
// HW_PRINT("HW:: AD9371 dynamic configuration initialization failed!\n");
// return ADIERR_FAILED;
// }
//
// printf("HW:: AD9371 ready to be reconfigured!\n");
// HW_PRINT("HW:: AD9371 ready to be reconfigured!\n");
//
// // main loop
// while(1);
@@ -101,57 +101,64 @@ int HARDWARE_ad9371Config(void)
/*********** Initialize Configuration Interface ***********/
/**********************************************************/
Status = CMB_initPlatform();
if (Status != ADIERR_OK){
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
Status = HW_adiCfgProfileInit();
if (Status != ADIERR_OK){
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
printf("HW:: Initialize configuration interface done!\n");
HW_PRINT("HW:: Initialize configuration interface done!\n");
/**********************************************************/
/****************** AD9528 Configuration ******************/
/**********************************************************/
Status = HW_9528Config(ad9528Init);
if (Status != ADIERR_OK){
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
printf("HW:: AD9528 configuration done!\n");
HW_PRINT("HW:: AD9528 configuration done!\n");
Status = HW_9528GetLockStatus(ad9528Init, &reg508);
if (Status != ADIERR_OK){
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
printf("HW:: AD9528 REG508: 0x%02x\n",reg508);
HW_PRINT("HW:: AD9528 REG508: 0x%02x\n", reg508);
/**********************************************************/
/****************** AD9371 Configuration ******************/
/**********************************************************/
Status = HW_9371Config(ad9528Init, &mykDevice);
if (Status != ADIERR_OK){
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
Status = HW_9371CheckJesdStatus(&mykDevice, &framerStatus,
&obsFramerStatus, &deframerStatus);
if (Status != ADIERR_OK){
if (Status != ADIERR_OK)
{
return ADIERR_FAILED;
}
else {
else
{
// typical value: 0x3E
printf("HW:: RxFramerStatus = 0x%x\n", framerStatus);
HW_PRINT("HW:: RxFramerStatus = 0x%x\n", framerStatus);
// typical value: 0x3E
printf("HW:: OrxFramerStatus = 0x%x\n", obsFramerStatus);
HW_PRINT("HW:: OrxFramerStatus = 0x%x\n", obsFramerStatus);
// typical value: 0x28
printf("HW:: DeframerStatus = 0x%x\n", deframerStatus);
HW_PRINT("HW:: DeframerStatus = 0x%x\n", deframerStatus);
}
printf("HW:: All configuration done!\n");
HW_PRINT("HW:: All configuration done!\n");
return ADIERR_OK;
}
@@ -163,7 +170,7 @@ int HARDWARE_ad9371Config(void)
//
// Status = HW_setupIntrSystem(INTC_DEVICE_ID, &Intc);
// if (Status != XST_SUCCESS) {
// printf("HW: HW_setupIntrSystem() failed!\n");
// HW_PRINT("HW: HW_setupIntrSystem() failed!\n");
// return XST_FAILURE;
// }
//
@@ -171,7 +178,7 @@ int HARDWARE_ad9371Config(void)
// Status |= XGpio_Initialize(&GpioGainCtrl, GAIN_CTRL_DEVICE_ID);
// Status |= XGpio_Initialize(&GpioAttnCtrl, ATTN_CTRL_DEVICE_ID);
// if (Status != XST_SUCCESS) {
// printf("HW: GPIO init failed!\n");
// HW_PRINT("HW: GPIO init failed!\n");
// return XST_FAILURE;
// }
//
@@ -229,14 +236,16 @@ int HW_setupIntrSystem(u16 DeviceId, XScuGic * GicPtr)
* use.
*/
CfgPtr = XScuGic_LookupConfig(DeviceId);
if (!CfgPtr) {
printf("No interrupt config found for %d\n", DeviceId);
if (!CfgPtr)
{
HW_PRINT("No interrupt config found for %d\n", DeviceId);
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(GicPtr, CfgPtr, CfgPtr->CpuBaseAddress);
if (Status != XST_SUCCESS) {
printf("No interrupt config found for %d\n", DeviceId);
if (Status != XST_SUCCESS)
{
HW_PRINT("No interrupt config found for %d\n", DeviceId);
return XST_FAILURE;
}
@@ -249,7 +258,6 @@ int HW_setupIntrSystem(u16 DeviceId, XScuGic * GicPtr)
return XST_SUCCESS;
}
int HW_connectIntr(XScuGic *GicPtr, u32 IntrId, Xil_InterruptHandler Handler,
void *CallBackRef, u8 Priority, u8 Trigger)
{
@@ -268,16 +276,17 @@ int HW_connectIntr(XScuGic *GicPtr,u32 IntrId,Xil_InterruptHandler Handler,
return XST_SUCCESS;
}
int HW_adiCfgProfileInit(void)
{
if (!ad9528Init) {
printf("Cannot find ad9528 configuration profile with name 'ad9528Init'!");
if (!ad9528Init)
{
HW_PRINT("Cannot find ad9528 configuration profile with name 'ad9528Init'!");
return ADIERR_FAILED;
}
if (!&mykDevice) {
printf("Cannot find ad9371 configuration profile with name 'mykDevice'!");
if (!&mykDevice)
{
HW_PRINT("Cannot find ad9371 configuration profile with name 'mykDevice'!");
return ADIERR_FAILED;
}
@@ -293,7 +302,6 @@ int HW_adiCfgProfileInit(void)
return ADIERR_OK;
}
int HW_9528Config(ad9528Device_t *clockAD9528_device)
{
ADI_ERR error;
@@ -303,8 +311,9 @@ int HW_9528Config(ad9528Device_t *clockAD9528_device)
/* Perform a hard reset on the AD9528 DUT */
error = AD9528_resetDevice(clockAD9528_device);
if (error != ADIERR_OK) {
printf("AD9528_resetDevice() failed\n");
if (error != ADIERR_OK)
{
HW_PRINT("AD9528_resetDevice() failed\n");
return ADIERR_FAILED;
}
@@ -312,35 +321,36 @@ int HW_9528Config(ad9528Device_t *clockAD9528_device)
clockAD9528_device->pll1Settings->vcxo_Frequency_Hz,
clockAD9528_device->pll1Settings->refA_Frequency_Hz,
clockAD9528_device->outputSettings->outFrequency_Hz[1]);
if (error != ADIERR_OK) {
printf("AD9528_initDeviceDataStruct() failed\n");
if (error != ADIERR_OK)
{
HW_PRINT("AD9528_initDeviceDataStruct() failed\n");
return ADIERR_FAILED;
}
/* Initialize the AD9528 by writing all SPI registers */
error = AD9528_initialize(clockAD9528_device);
if (error != ADIERR_OK) {
printf("WARNING: AD9528_initialize() issues.\n");
if (error != ADIERR_OK)
{
HW_PRINT("WARNING: AD9528_initialize() issues.\n");
}
return ADIERR_OK;
}
int HW_9528GetLockStatus(ad9528Device_t *device, uint8_t *reg508)
{
ADI_ERR error;
error = CMB_SPIReadByte(device->spiSettings, AD9528_ADDR_STATUS_READBACK0, reg508);
if (error != ADIERR_OK) {
printf("HW_9528GetLockStatus failed.\n");
if (error != ADIERR_OK)
{
HW_PRINT("HW_9528GetLockStatus failed.\n");
return ADIERR_FAILED;
}
return ADIERR_OK;
}
int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice)
{
ADI_ERR error;
@@ -365,19 +375,19 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
/* Allocating memory for the errorString */
errorString = NULL;
/*************************************************************************/
/***** Mykonos Initialization Sequence *****/
/*************************************************************************/
/* Perform a hard reset on the MYKONOS DUT (Toggle RESETB pin on device) */
if ((mykError = MYKONOS_resetDevice(mykDevice)) != MYKONOS_ERR_OK) {
if ((mykError = MYKONOS_resetDevice(mykDevice)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_initialize(mykDevice)) != MYKONOS_ERR_OK) {
if ((mykError = MYKONOS_initialize(mykDevice)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
@@ -387,7 +397,8 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
/*************************************************************************/
if ((mykError = MYKONOS_checkPllsLockStatus(mykDevice,
&pllLockStatus)) != MYKONOS_ERR_OK) {
&pllLockStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
@@ -397,7 +408,8 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
/*************************************************************************/
if ((mykError = MYKONOS_enableMultichipSync(mykDevice, 1,
&mcsStatus)) != MYKONOS_ERR_OK) {
&mcsStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
@@ -418,34 +430,40 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
/*************************************************************************/
if ((mykError = MYKONOS_enableMultichipSync(mykDevice, 0,
&mcsStatus)) != MYKONOS_ERR_OK) {
&mcsStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mcsStatus & 0x0B) == 0x0B)
printf("MCS successful\n");
HW_PRINT("MCS successful\n");
else
printf("MCS failed\n");
HW_PRINT("MCS failed\n");
/*************************************************************************/
/***** Mykonos Load ARM file *****/
/*************************************************************************/
if (pllLockStatus & 0x01) {
printf("CLKPLL locked\n");
if ((mykError = MYKONOS_initArm(mykDevice)) != MYKONOS_ERR_OK) {
if (pllLockStatus & 0x01)
{
HW_PRINT("CLKPLL locked\n");
if ((mykError = MYKONOS_initArm(mykDevice)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_loadArmFromBinary(mykDevice,
&firmware_Mykonos_M3_bin[0], firmware_Mykonos_M3_bin_len)) != MYKONOS_ERR_OK) {
&firmware_Mykonos_M3_bin[0], firmware_Mykonos_M3_bin_len)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
} else {
printf("CLKPLL not locked (0x%x)\n", pllLockStatus);
}
else
{
HW_PRINT("CLKPLL not locked (0x%x)\n", pllLockStatus);
error = ADIERR_FAILED;
goto error_2;
}
@@ -453,26 +471,29 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
/* Read back the version of the ARM binary loaded into the Mykonos ARM memory */
if ((mykError = MYKONOS_getArmVersion(mykDevice, &arm_major, &arm_minor,
&arm_release, NULL)) == MYKONOS_ERR_OK)
printf("AD9371 ARM version %d.%d.%d\n", arm_major, arm_minor, arm_release);
HW_PRINT("AD9371 ARM version %d.%d.%d\n", arm_major, arm_minor, arm_release);
/*************************************************************************/
/***** Mykonos Set RF PLL Frequencies *****/
/*************************************************************************/
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, RX_PLL,
mykDevice->rx->rxPllLoFrequency_Hz)) != MYKONOS_ERR_OK) {
mykDevice->rx->rxPllLoFrequency_Hz)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL,
mykDevice->tx->txPllLoFrequency_Hz)) != MYKONOS_ERR_OK) {
mykDevice->tx->txPllLoFrequency_Hz)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, SNIFFER_PLL,
mykDevice->obsRx->snifferPllLoFrequency_Hz)) != MYKONOS_ERR_OK) {
mykDevice->obsRx->snifferPllLoFrequency_Hz)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
@@ -481,15 +502,17 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
mdelay(200);
if ((mykError = MYKONOS_checkPllsLockStatus(mykDevice,
&pllLockStatus)) != MYKONOS_ERR_OK) {
&pllLockStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((pllLockStatus & 0x0F) == 0x0F)
printf("PLLs locked\n");
else {
printf("PLLs not locked (0x%x)\n", pllLockStatus);
HW_PRINT("PLLs locked\n");
else
{
HW_PRINT("PLLs not locked (0x%x)\n", pllLockStatus);
error = ADIERR_FAILED;
goto error_2;
}
@@ -592,56 +615,67 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
/*************************************************************************/
if ((mykError = MYKONOS_runInitCals(mykDevice,
(initCalMask & ~TX_LO_LEAKAGE_EXTERNAL))) != MYKONOS_ERR_OK) {
(initCalMask & ~TX_LO_LEAKAGE_EXTERNAL))) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_waitInitCals(mykDevice, 60000, &errorFlag,
&errorCode)) != MYKONOS_ERR_OK) {
&errorCode)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((errorFlag != 0) || (errorCode != 0)) {
if ((errorFlag != 0) || (errorCode != 0))
{
/*** < Info: abort init cals > ***/
if ((mykError = MYKONOS_abortInitCals(mykDevice,
&initCalsCompleted)) != MYKONOS_ERR_OK) {
&initCalsCompleted)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if (initCalsCompleted)
printf("Completed calibrations: %x\n", (unsigned int)initCalsCompleted);
} else
printf("Calibrations completed successfully\n");
HW_PRINT("Completed calibrations: %x\n", (unsigned int)initCalsCompleted);
}
else
HW_PRINT("Calibrations completed successfully\n");
/*************************************************************************/
/***** Mykonos ARM Initialization External LOL Calibrations with PA *****/
/*************************************************************************/
/* Please ensure PA is enabled operational at this time */
if (initCalMask & TX_LO_LEAKAGE_EXTERNAL) {
if (initCalMask & TX_LO_LEAKAGE_EXTERNAL)
{
if ((mykError = MYKONOS_runInitCals(mykDevice,
TX_LO_LEAKAGE_EXTERNAL)) != MYKONOS_ERR_OK) {
TX_LO_LEAKAGE_EXTERNAL)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_waitInitCals(mykDevice, 60000, &errorFlag,
&errorCode)) != MYKONOS_ERR_OK) {
&errorCode)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((errorFlag != 0) || (errorCode != 0)) {
if ((errorFlag != 0) || (errorCode != 0))
{
/*** < Info: abort init cals > ***/
if ((mykError = MYKONOS_abortInitCals(mykDevice,
&initCalsCompleted)) != MYKONOS_ERR_OK) {
&initCalsCompleted)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
} else
printf("External LOL Calibrations completed successfully\n");
}
else
HW_PRINT("External LOL Calibrations completed successfully\n");
}
/*************************************************************************/
@@ -649,7 +683,8 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
/*************************************************************************/
if ((mykError = MYKONOS_enableSysrefToRxFramer(mykDevice,
1)) != MYKONOS_ERR_OK) {
1)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
@@ -657,7 +692,8 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
* transmitting CGS from the RxFramer> ***/
if ((mykError = MYKONOS_enableSysrefToObsRxFramer(mykDevice,
1)) != MYKONOS_ERR_OK) {
1)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
@@ -665,18 +701,20 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
* transmitting CGS from the ObsRxFramer> ***/
if ((mykError = MYKONOS_enableSysrefToDeframer(mykDevice,
0)) != MYKONOS_ERR_OK) {
0)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_resetDeframer(mykDevice)) != MYKONOS_ERR_OK) {
if ((mykError = MYKONOS_resetDeframer(mykDevice)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_enableSysrefToDeframer(mykDevice,
1)) != MYKONOS_ERR_OK) {
if ((mykError = MYKONOS_enableSysrefToDeframer(mykDevice, 1)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
@@ -704,7 +742,8 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
/*************************************************************************/
if ((mykError = MYKONOS_enableTrackingCals(mykDevice,
trackingCalMask)) != MYKONOS_ERR_OK) {
trackingCalMask)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
@@ -714,19 +753,22 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
/*** < Info: Function to turn radio on, Enables transmitters and receivers
* that were setup during MYKONOS_initialize() > ***/
if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK) {
if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
/*** < Info: Allow TxQEC to run when User: is not actively using ORx receive path > ***/
if ((mykError = MYKONOS_setObsRxPathSource(mykDevice,
OBS_RXOFF)) != MYKONOS_ERR_OK) {
OBS_RXOFF)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
if ((mykError = MYKONOS_setObsRxPathSource(mykDevice,
OBS_INTERNALCALS)) != MYKONOS_ERR_OK) {
OBS_INTERNALCALS)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
@@ -734,26 +776,26 @@ int HW_9371Config(ad9528Device_t *clockAD9528_device, mykonosDevice_t *mykDevice
mdelay(1000);
if ((mykError = MYKONOS_setObsRxPathSource(mykDevice,
OBS_RX1_SNIFFERLO)) != MYKONOS_ERR_OK) {
OBS_RX1_SNIFFERLO)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
goto error_11;
}
Xil_DCacheInvalidateRange(DDR_MEM_BASEADDR + 0x800000, 16384 * 8);
printf("Done\n");
HW_PRINT("Done\n");
return 0;
error_11:
printf("%s", errorString);
HW_PRINT("%s", errorString);
error_2:
// axi_clkgen_remove(rx_clkgen);
return FAILURE;
}
int HW_9371CheckJesdStatus(mykonosDevice_t *mykDevice, uint8_t *framerStatus,
uint8_t *obsFramerStatus, uint8_t *deframerStatus)
{
@@ -767,19 +809,24 @@ int HW_9371CheckJesdStatus(mykonosDevice_t *mykDevice, uint8_t *framerStatus,
/*************************************************************************/
if ((mykError = MYKONOS_readRxFramerStatus(mykDevice,
framerStatus)) != MYKONOS_ERR_OK) {
framerStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
return ADIERR_FAILED;
}
else {
else
{
// typical value: 0x3E
}
if ((mykError = MYKONOS_readOrxFramerStatus(mykDevice,
obsFramerStatus)) != MYKONOS_ERR_OK) {
obsFramerStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
return ADIERR_FAILED;
} else {
}
else
{
// typical value: 0x3E
}
@@ -788,17 +835,19 @@ int HW_9371CheckJesdStatus(mykonosDevice_t *mykDevice, uint8_t *framerStatus,
/*************************************************************************/
if ((mykError = MYKONOS_readDeframerStatus(mykDevice,
deframerStatus)) != MYKONOS_ERR_OK) {
deframerStatus)) != MYKONOS_ERR_OK)
{
errorString = getMykonosErrorMessage(mykError);
return ADIERR_FAILED;
} else {
}
else
{
// typical value: 0x28
}
return ADIERR_OK;
}
int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
{
mykonosErr_t mykError = MYKONOS_ERR_OK;
@@ -808,7 +857,7 @@ int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
*/
if ((mykError = MYKONOS_radioOff(mykDevice)) != MYKONOS_ERR_OK)
{
printf("Turn radio off failed!\n\r");
HW_PRINT("Turn radio off failed!\n\r");
return ADIERR_FAILED;
}
@@ -818,14 +867,14 @@ int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL,
freq_Hz)) != MYKONOS_ERR_OK)
{
printf("Set TX PLL failed!\n\r");
HW_PRINT("Set TX PLL failed!\n\r");
return ADIERR_FAILED;
}
mykError = MYKONOS_checkPllsLockStatus(mykDevice, &pllLockStatus);
if ((pllLockStatus & 0x07) != 0x07)
{
/*** < Info: Clock, Rx and Tx PLLs not locked > ***/
printf("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
HW_PRINT("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
}
/*
@@ -834,7 +883,7 @@ int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
// If((mykError = MYKONOS_resetExtTxLolChannel(mykDevice, TX1_TX2))
// != MYKONOS_ERR_OK) ; //where TX1_TX2 is part of the enum mykonosTxChannels_t
// {
// printf("Reset external channel FAILED!");
// HW_PRINT("Reset external channel FAILED!");
// }
/*
@@ -842,7 +891,7 @@ int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
*/
if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK)
{
printf("Turn radio on failed!\n\r");
HW_PRINT("Turn radio on failed!\n\r");
return ADIERR_FAILED;
}
@@ -852,12 +901,11 @@ int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
// If((mykError = MYKONOS_MYKONOS_setObsRxPathSource(mykDevice, OBS_INTERNALCALS))
// != MYKONOS_ERR_OK) ; //where TX1_TX2 is part of the enum mykonosTxChannels_t
// {
// printf("Reenable tracking calibrations FAILED!");
// HW_PRINT("Reenable tracking calibrations FAILED!");
// }
return ADIERR_OK;
}
int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
{
mykonosErr_t mykError = MYKONOS_ERR_OK;
@@ -875,7 +923,7 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
*/
if ((mykError = MYKONOS_radioOff(mykDevice)) != MYKONOS_ERR_OK)
{
printf("Turn radio off failed!\n\r");
HW_PRINT("Turn radio off failed!\n\r");
return ADIERR_FAILED;
}
@@ -885,14 +933,14 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
if ((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL,
freq_Hz)) != MYKONOS_ERR_OK)
{
printf("Set TX PLL failed!\n\r");
HW_PRINT("Set TX PLL failed!\n\r");
return ADIERR_FAILED;
}
mykError = MYKONOS_checkPllsLockStatus(mykDevice, &pllLockStatus);
if ((pllLockStatus & 0x07) != 0x07)
{
/*** < Info: Clock, Rx and Tx PLLs not locked > ***/
printf("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
HW_PRINT("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
}
/*
@@ -900,34 +948,30 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
*/
uint32_t initCalMask = TX_QEC_INIT | LOOPBACK_RX_LO_DELAY |
LOOPBACK_RX_RX_QEC_INIT | RX_LO_DELAY | RX_QEC_INIT;
if ((mykError = MYKONOS_runInitCals(mykDevice, initCalMask))
!= MYKONOS_ERR_OK)
if ((mykError = MYKONOS_runInitCals(mykDevice, initCalMask)) != MYKONOS_ERR_OK)
{
printf("Rerun the initialization calibrations FAILED!");
HW_PRINT("Rerun the initialization calibrations FAILED!");
return ADIERR_FAILED;
}
if ((mykError = MYKONOS_waitInitCals(mykDevice, 60000, &errorFlag,
&errorCode)) != MYKONOS_ERR_OK)
{
printf("Initialize calibration TIME OUT!");
HW_PRINT("Initialize calibration TIME OUT!");
return ADIERR_FAILED;
}
if ((errorFlag != 0) || (errorCode != 0))
{
printf("initial cals error!\n\r");
HW_PRINT("initial cals error!\n\r");
if((mykError = MYKONOS_getInitCalStatus(mykDevice, &initCalStatus))
!= MYKONOS_ERR_OK)
if ((mykError = MYKONOS_getInitCalStatus(mykDevice, &initCalStatus)) != MYKONOS_ERR_OK)
{
/*** < User log error return value to debug why init failed > ***/
}
// abort init calibrations
if((mykError = MYKONOS_abortInitCals(mykDevice, &initCalsCompleted))
!= MYKONOS_ERR_OK)
if ((mykError = MYKONOS_abortInitCals(mykDevice, &initCalsCompleted)) != MYKONOS_ERR_OK)
{
/*** < User log error return value to debug why init failed > ***/
}
if (initCalsCompleted)
{
@@ -938,10 +982,8 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
{
/*** < User log error return value to debug why init failed > ***/
}
if((mykError = MYKONOS_readArmCmdStatusByte(mykDevice, 2, &status))
!= MYKONOS_ERR_OK)
if ((mykError = MYKONOS_readArmCmdStatusByte(mykDevice, 2, &status)) != MYKONOS_ERR_OK)
{
}
if (status != 0)
{
@@ -955,26 +997,25 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
*/
if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK)
{
printf("Turn radio on failed!\n\r");
HW_PRINT("Turn radio on failed!\n\r");
return ADIERR_FAILED;
}
return ADIERR_OK;
}
// void FreqIntrHandler(void *CallbackRef)
// {
// XGpio *GpioPtr = (XGpio *)CallbackRef;
// uint8_t IntrStatus;
// uint32_t NewFreqHz;
// IntrStatus = XGpio_InterruptGetStatus(GpioPtr);
//
// if (IntrStatus & XGPIO_IR_CH1_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH1_MASK);
//
// NewFreqHz = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_1);
// if (NewFreqHz != mykDevice.tx->txPllLoFrequency_Hz)
// {
@@ -989,20 +1030,20 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
// HW_9371LargeFrequencyChange(&mykDevice, NewFreqHz);
// }
// mykDevice.tx->txPllLoFrequency_Hz = NewFreqHz;
// printf("New Tx frequency set to %d Hz!\n",NewFreqHz);
// HW_PRINT("New Tx frequency set to %d Hz!\n", NewFreqHz);
// }
// else
// {
// printf("The desired Tx Frequency is out of range(300 ~ 6000 MHz)!\n");
// HW_PRINT("The desired Tx Frequency is out of range(300 ~ 6000 MHz)!\n");
// }
// }
// }
//
// if (IntrStatus & XGPIO_IR_CH2_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH2_MASK);
//
// NewFreqHz = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_2);
// if (NewFreqHz != mykDevice.rx->rxPllLoFrequency_Hz)
// {
@@ -1017,29 +1058,28 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
// HW_9371LargeFrequencyChange(&mykDevice, NewFreqHz);
// }
// mykDevice.rx->rxPllLoFrequency_Hz = NewFreqHz;
// printf("New Rx frequency set to %d Hz!\n",NewFreqHz);
// HW_PRINT("New Rx frequency set to %d Hz!\n", NewFreqHz);
// }
// else
// {
// printf("The desired Rx Frequency is out of range(300 ~ 6000 MHz)!\n");
// HW_PRINT("The desired Rx Frequency is out of range(300 ~ 6000 MHz)!\n");
// }
// }
// }
// }
//
//
// void GainIntrHandler(void *CallbackRef)
// {
// XGpio *GpioPtr = (XGpio *)CallbackRef;
// uint8_t IntrStatus;
// uint32_t NewRxGain;
// IntrStatus = XGpio_InterruptGetStatus(GpioPtr);
//
// if (IntrStatus & XGPIO_IR_CH1_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH1_MASK);
//
// NewRxGain = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_1);
// if (NewRxGain != mykDevice.rx->rxGainCtrl->rx1GainIndex)
// {
@@ -1048,21 +1088,21 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
// MYKONOS_setRx1ManualGain(&mykDevice, NewRxGain);
// mykDevice.rx->rxGainCtrl->rx1GainIndex = NewRxGain;
// char buf[BUFSIZ];
// sprintf(buf, "%u", NewRxGain);
// printf("New Rx1 gain index set to %s!\n",buf);
// sHW_PRINT(buf, "%u", NewRxGain);
// HW_PRINT("New Rx1 gain index set to %s!\n", buf);
// }
// else
// {
// printf("The desired Rx1 gain index is out of range(195 ~ 255), 0.5dB per stage!\n");
// HW_PRINT("The desired Rx1 gain index is out of range(195 ~ 255), 0.5dB per stage!\n");
// }
// }
// }
//
// if (IntrStatus & XGPIO_IR_CH2_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH2_MASK);
//
// NewRxGain = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_2);
// if (NewRxGain != mykDevice.rx->rxGainCtrl->rx2GainIndex)
// {
@@ -1071,30 +1111,29 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
// MYKONOS_setRx2ManualGain(&mykDevice, NewRxGain);
// mykDevice.rx->rxGainCtrl->rx2GainIndex = NewRxGain;
// char buf[BUFSIZ];
// sprintf(buf, "%u", NewRxGain);
// printf("New Rx2 gain index set to %s!\n",buf);
// sHW_PRINT(buf, "%u", NewRxGain);
// HW_PRINT("New Rx2 gain index set to %s!\n", buf);
// }
// else
// {
// printf("The desired Rx2 gain index is out of range(195 ~ 255), 0.5dB per stage!\n");
// HW_PRINT("The desired Rx2 gain index is out of range(195 ~ 255), 0.5dB per stage!\n");
// }
// }
// }
// }
//
//
// void AttnIntrHandler(void *CallbackRef)
// {
// XGpio *GpioPtr = (XGpio *)CallbackRef;
// uint8_t IntrStatus;
// uint32_t NewTxAttn;
// IntrStatus = XGpio_InterruptGetStatus(GpioPtr);
//
// if (IntrStatus & XGPIO_IR_CH1_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH1_MASK);
//
// NewTxAttn = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_1);
// if (NewTxAttn != mykDevice.tx->tx1Atten_mdB)
// {
@@ -1103,21 +1142,21 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
// MYKONOS_setTx1Attenuation(&mykDevice, NewTxAttn);
// mykDevice.tx->tx1Atten_mdB = NewTxAttn;
// char buf[BUFSIZ];
// sprintf(buf, "%u", NewTxAttn);
// printf("New Tx1 attenuation set to %s dBm!\n",buf);
// sHW_PRINT(buf, "%u", NewTxAttn);
// HW_PRINT("New Tx1 attenuation set to %s dBm!\n", buf);
// }
// else
// {
// printf("The desired Tx1 attenuation is out of range(0 ~ 41950 dBm), 50 dBm step!\n");
// HW_PRINT("The desired Tx1 attenuation is out of range(0 ~ 41950 dBm), 50 dBm step!\n");
// }
// }
// }
//
// if (IntrStatus & XGPIO_IR_CH2_MASK)
// {
// /* Clear the Interrupt */
// XGpio_InterruptClear(GpioPtr, XGPIO_IR_CH2_MASK);
//
// NewTxAttn = XGpio_DiscreteRead(GpioPtr, AXI_GPIO_BANK_2);
// if (NewTxAttn != mykDevice.tx->tx2Atten_mdB)
// {
@@ -1126,12 +1165,12 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
// MYKONOS_setTx2Attenuation(&mykDevice, NewTxAttn);
// mykDevice.tx->tx2Atten_mdB = NewTxAttn;
// char buf[BUFSIZ];
// sprintf(buf, "%u", NewTxAttn);
// printf("New Tx2 attenuation set to %s dBm!\n",buf);
// sHW_PRINT(buf, "%u", NewTxAttn);
// HW_PRINT("New Tx2 attenuation set to %s dBm!\n", buf);
// }
// else
// {
// printf("The desired Tx2 attenuation is out of range(0 ~ 41950 dBm), 50 dBm step!\n");
// HW_PRINT("The desired Tx2 attenuation is out of range(0 ~ 41950 dBm), 50 dBm step!\n");
// }
// }
// }
+3 -2
View File
@@ -1,7 +1,7 @@
/*
* headless.h
*
* Created on: 2021Äê6ÔÂ8ÈÕ
* Created on: 2021��6��8��
* Author: Josh
*/
@@ -30,7 +30,8 @@
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define HW_PRINT(...) __asm__("nop")
// #define HW_PRINT(...) printf(__VA_ARGS__)
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
+188 -118
View File
@@ -36,7 +36,7 @@
#include "timer.h"
#include "config/app_config.h"
#include "dev_profile/dev_profile.h"
#include "systembus/systembus.h"
#include "mpc/mpc.h"
#include "networking/phy_layer/phy_layer.h"
#include "networking/link_layer/link_layer.h"
// RF-Driver
@@ -48,41 +48,46 @@ 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);
void Mpc_RxIntrHandler(void *context);
void Mpc_TxIntrHandler(void *context);
/************************** Constant Definitions *****************************/
struct callback_desc phy_callback_desc = {
struct callback_desc phy_callback_desc =
{
.callback = Phy_IntrHandler,
.ctx = NULL
};
struct callback_desc periodicpull_callback_desc = {
struct callback_desc periodicpull_callback_desc =
{
.callback = PeriodicPull_Handler,
.ctx = NULL
};
struct callback_desc sysbus_rx_callback_desc = {
.callback = Systembus_RxIntrHandler,
struct callback_desc mpc_rx_callback_desc =
{
.callback = Mpc_RxIntrHandler,
.ctx = NULL
};
struct callback_desc sysbus_tx_callback_desc = {
.callback = Systembus_TxIntrHandler,
struct callback_desc mpc_tx_callback_desc =
{
.callback = Mpc_TxIntrHandler,
.ctx = NULL
};
struct callback_desc scutm_callback_desc = {
struct callback_desc scutm_callback_desc =
{
.callback = ScuTimer_IntrHandler,
.ctx = NULL
};
L2_CONFIG linkConfig = {
L2_CONFIG linkConfig =
{
.myType = L2_NODE_HEAD,
.clustId = 1,
.myId = 1,
.headId = 1,
.bkpHeadId = 0,
.netScale = 2,
.phyInstPtr = NULL, // physical layer reference
.tmcInstPtr = NULL
@@ -93,35 +98,83 @@ L2_CONFIG linkConfig = {
// .clustId = 1,
// .myId = 2,
// .headId = 1,
// .bkpHeadId = 0,
// .netScale = 2,
// .phyInstPtr = NULL, // physical layer reference
// .tmcInstPtr = NULL
// };
static PHY_CONFIG phyConfig = {
static PHY_CONFIG phyConfig =
{
.devId = 0,
.baseAddr = PHY_BASEADDR,
.antBramId = PHY_ANTCONFIG_BRAM_DEVICE_ID,
.antInfoBramId = -1,
.txBramId = PHY_TXBUFF_BRAM_DEVICE_ID,
.rxBramId = PHY_RXBUFF_BRAM_DEVICE_ID,
.hwXadcId = PHY_HW_XADC_DEVICE_ID
.hwXadcId = PHY_HW_XADC_DEVICE_ID,
.get_clk_state = NULL,
.get_ad_lock_state = NULL,
.get_ad0_temp = NULL,
.get_ad1_temp = NULL
};
TMC_CONFIG tmcConfig = {
TMC_CONFIG tmcConfig =
{
.baseAddr = TIME_CONTROLLER_BASEADDR,
.reset = 10
};
//static SYSBUS_CONFIG sysbusConfig = {
// .baseAddr = SYSBUS_BASE_ADDR,
// .txQueueMax = 16,
// .rxQueueMax = 16
//};
static MPC_CONFIG mpcConfig = {
.bramId = MPC_BRAM_ID,
.gpioId = MPC_GPIO_ID,
.txQueueMax = 16,
.rxQueueMax = 16
};
#ifdef APP_EMULATE_DATA
uint8_t testDataLj[] =
{
0xEA, 0xDF, 0x3F, 0x27, 0xCE, 0x9B, 0xE6, 0x3F,
0xB5, 0xA3, 0x38, 0x47, 0x1D, 0x1D, 0xFA, 0x3F,
0x39, 0xB4, 0xC8, 0x76, 0xBE, 0xAB, 0x8E, 0x40,
0xC9, 0xE8, 0x80, 0x24, 0xEC, 0xCB, 0x13, 0x40,
0x37, 0x38, 0x7F, 0x22, 0x72, 0x06, 0xF0, 0x01,
0x00, 0x00, 0xB8, 0xAA, 0x08, 0x47, 0x1E, 0xC6,
0xB0, 0x47, 0x54, 0xFD, 0xEB, 0x45, 0xA1, 0x8A,
0x86, 0x44, 0x43, 0xB6, 0xC8, 0x44, 0x4E, 0x19,
0xA8, 0x42
};
uint8_t testDataFlj[] =
{
0xFD, 0x1E, 0xA5, 0x22, 0x72, 0x02, 0x5A, 0x02,
0x00, 0x00, 0x81, 0x97, 0x39, 0x3F, 0xF1, 0xF4,
0xC0, 0x3F, 0x27, 0xF1, 0x65, 0x44, 0x53, 0x5C,
0xD3, 0x3F, 0xB5, 0x24, 0xA6, 0x22, 0x72, 0x02,
0x83, 0x01, 0x00, 0x00, 0xFC, 0xE0, 0x44, 0x47,
0xB7, 0x83, 0x35, 0x47, 0xA4, 0xBF, 0xE5, 0xC4,
0xE8, 0xDC, 0xD1, 0x44, 0x5D, 0x5D, 0xE7, 0x44,
0x7D, 0x1B, 0xE8, 0xC1, 0x60, 0x97, 0x57, 0x42,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5D, 0x86, 0xA6, 0x22, 0x72, 0x02, 0xA5, 0x02,
0x00, 0x00, 0x97, 0x4E, 0xB5, 0x47, 0xC4, 0x2A,
0xB0, 0x47, 0x2D, 0x00, 0x21, 0xC5, 0x8A, 0x85,
0xD1, 0x44, 0x23, 0xFD, 0xC8, 0x44, 0xA1, 0xC4,
0xEA, 0xC1, 0x91, 0x4E, 0x71, 0xC2, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0xAD,
0xA6, 0x22, 0x72, 0x02, 0xA5, 0x02, 0x00, 0x00,
0xCD, 0x07, 0xD6, 0x47, 0x1D, 0xA4, 0xCE, 0x47,
0x6E, 0x61, 0x33, 0xC5, 0x85, 0x55, 0xD1, 0x44,
0x9C, 0x16, 0xBD, 0x44, 0x36, 0xC0, 0xEB, 0xC1,
0xF0, 0xFF, 0x5B, 0x42, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x78, 0x25, 0x03, 0x00
};
#endif
/************************** Function Prototypes ******************************/
static struct irq_ctrl_desc *intcDescPtr; // General interrupt controller descriptor
static struct timer_desc *logTmPtr;
static SYSBUS *sysbusDescPtr;
static MPC *mpcDescPtr;
static PHY_INST *phyInstPtr;
static TMC_INST *tmcInstPtr = NULL;
L2_INST *linkInstPtr;
@@ -200,64 +253,64 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
return Status;
}
// /* Initialize system bus interrupt. */
// Status = irq_trigger_level_set(descPtr, SYSBUS_TX_INTR_ID, IRQ_EDGE_RISING);
// if (Status != SUCCESS)
// {
// DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
// return Status;
// }
// // Set interrupt priority
// Status = irq_set_priority(descPtr, SYSBUS_TX_INTR_ID, 0x10);
// if (Status != SUCCESS)
// {
// DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
// return Status;
// }
//
// // Connect the interrupt service routine isr1 to the interrupt controller
// Status = irq_register_callback(descPtr, SYSBUS_TX_INTR_ID, &sysbus_tx_callback_desc);
// if (Status != SUCCESS)
// {
// DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
// return Status;
// }
// Status = irq_trigger_level_set(descPtr, SYSBUS_RX_INTR_ID, IRQ_EDGE_RISING);
// if (Status != SUCCESS)
// {
// DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
// return Status;
// }
// // Set interrupt priority
// Status = irq_set_priority(descPtr, SYSBUS_RX_INTR_ID, 0x18);
// if (Status != SUCCESS)
// {
// DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
// return Status;
// }
//
// // Connect the interrupt service routine isr1 to the interrupt controller
// Status = irq_register_callback(descPtr, SYSBUS_RX_INTR_ID, &sysbus_rx_callback_desc);
// if (Status != SUCCESS)
// {
// DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
// return Status;
// }
//
// /* Initialize Scu timer interrupt. */
// // Connect the interrupt service routine isr1 to the interrupt controller
// Status = irq_register_callback(descPtr, SCUTIMER_INTR_ID, &scutm_callback_desc);
// if (Status != SUCCESS)
// {
// DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
// return Status;
// }
/* Initialize system bus interrupt. */
Status = irq_trigger_level_set(descPtr, MPC_TX_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt priority
Status = irq_set_priority(descPtr, MPC_TX_INTR_ID, 0x10);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, MPC_TX_INTR_ID, &mpc_tx_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
Status = irq_trigger_level_set(descPtr, MPC_RX_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt priority
Status = irq_set_priority(descPtr, MPC_RX_INTR_ID, 0x18);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, MPC_RX_INTR_ID, &mpc_rx_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
/* Initialize Scu timer interrupt. */
// Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, SCUTIMER_INTR_ID, &scutm_callback_desc);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Enable interrupts
irq_enable(descPtr, PHY_INTR_ID);
irq_enable(descPtr, PERIODIC_5MS_INTR_ID);
// irq_enable(descPtr, SYSBUS_RX_INTR_ID);
// irq_enable(descPtr, SYSBUS_TX_INTR_ID);
irq_enable(descPtr, MPC_RX_INTR_ID);
irq_enable(descPtr, MPC_TX_INTR_ID);
irq_enable(descPtr, SCUTIMER_INTR_ID);
// Enable Exceptions
@@ -315,13 +368,13 @@ void PeriodicPull_Handler(void *callBackRef)
* @return None.
*
******************************************************************************/
void Systembus_RxIntrHandler(void *context)
void Mpc_RxIntrHandler(void *context)
{
int32_t Status;
Status = SystemBus_RxIntrHandler(sysbusDescPtr);
Status = Mpc_RxIrqHandler(mpcDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("SystemBus_RxIntrHandler exit with error code %" PRId32 ",\n", Status);
DBG_ERROR("Mpc_RxIrqHandler exit with error code %" PRId32 ",\n", Status);
}
}
@@ -334,13 +387,13 @@ void Systembus_RxIntrHandler(void *context)
* @return None.
*
******************************************************************************/
void Systembus_TxIntrHandler(void *context)
void Mpc_TxIntrHandler(void *context)
{
int32_t Status;
Status = SystemBus_TxIntrHandler(sysbusDescPtr);
Status = Mpc_TxIrqHandler(mpcDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("SystemBus_TxIntrHandler exit with error code %" PRId32 ",\n", Status);
DBG_ERROR("Mpc_TxIrqHandler exit with error code %" PRId32 ",\n", Status);
}
}
@@ -359,8 +412,31 @@ void ScuTimer_IntrHandler(void *context)
xdesc = (struct xil_timer_desc *)(logTmPtr->extra);
if (XScuTimer_IsExpired((XScuTimer *)xdesc->instance))
{
// Update log
Phy_UpdateHwSate(phyInstPtr);
// Refresh log
Phy_RefreshHwSate(phyInstPtr);
if (TimeCtrl_GetIntCnt(tmcInstPtr) - phyInstPtr->lastLogTime >= PHY_LOG_EXPIRE)
{
Phy_UpdateLogging(phyInstPtr);
}
if (Mpc_IsEnable(mpcDescPtr))
{
if (Mpc_PendRemoteTest(mpcDescPtr) != SUCCESS)
{
DBG_ERROR("Failed to apply remote test.\n");
}
#ifdef APP_EMULATE_DATA
if (L2_GetNodeType(linkInstPtr) == L2_NODE_HEAD)
{
SysMonitor_UpdateSendPayload(testDataFlj, PAYLOAD_LEN_FLJ_TX);
}
else
{
SysMonitor_UpdateSendPayload(testDataLj, PAYLOAD_LEN_LJ_TX);
}
#endif
}
XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
}
else
@@ -420,7 +496,7 @@ int main(void)
}
/* Physical Layer Initialize */
Status = Phy_InstInit(&phyInstPtr, &phyConfig);
Status = Phy_Init(&phyInstPtr, &phyConfig);
if (Status == SUCCESS)
{
DBG_PRINT("Physical layer Init SUCCESS! \n");
@@ -445,13 +521,13 @@ int main(void)
return Status;
}
// /* System Bus Initialize */
// Status = SystemBus_Init(&sysbusDescPtr, &sysbusConfig);
// if (Status != SUCCESS)
// {
// DBG_ERROR("Systembus init FAILED, with error code: %" PRId32 "\n", Status);
// return Status;
// }
/* System Bus Initialize */
Status = Mpc_Init(&mpcDescPtr, &mpcConfig);
if (Status != SUCCESS)
{
DBG_ERROR("MPC init FAILED, with error code: %" PRId32 "\n", Status);
return Status;
}
/* System Monitor log timer Initialize */
Status = timer_init(&logTmPtr, &scutimer_init_param);
@@ -479,30 +555,24 @@ int main(void)
DBG_PRINT("Physical started...\n");
Phy_Start(phyInstPtr);
Linklayer_Start(linkInstPtr);
while (true);
// while (true)
// {
// // System bus handler
// if (SystemBus_IsReqPendding(sysbusDescPtr))
// {
// Status = SystemBus_HandleCmd(sysbusDescPtr);
// if (Status != SUCCESS)
// {
// DBG_ERROR("SystemBus_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
// }
// }
// if (SystemBus_IsRsqPendding(sysbusDescPtr) && (!SystemBus_IsTxBusy(sysbusDescPtr)))
// {
// // FIXME: Required by 12 (CASC)
// udelay(200);
// Status = SystemBus_MakeResp(sysbusDescPtr);
// if (Status != SUCCESS)
// {
// DBG_ERROR("SystemBus_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
// }
// }
// }
while (true)
{
// System bus handler
if (Mpc_IsReqPending(mpcDescPtr))
{
Status = Mpc_HandleCmd(mpcDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("Mpc_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
}
}
if (Mpc_IsRsqPending(mpcDescPtr) && (!Mpc_IsTxBusy(mpcDescPtr)))
{
Status = Mpc_MakeResp(mpcDescPtr);
if (Status != SUCCESS)
{
DBG_ERROR("Mpc_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
}
}
}
} // main
+566
View File
@@ -0,0 +1,566 @@
/*****************************************************************************/
/**
* Description: MPC protocol implementation file.
*
* Date: 2023-05-06 10:13
* Last Edit Time: [2023-05-06 21:45]
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
* [2023-09-13]: Update to 485 protocol-20220816
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Network
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "mpc.h"
#include "util.h"
#include "common.h"
#include "error.h"
#include "circ_queue.h"
#include "xbram.h"
#include "xgpio.h"
#include "../system_monitor.h"
/************************** Constant Definitions *****************************/
// Common Field
// -- Command word
#define WD_CMD 0x00
// -- Production type
#define WD_PRD 0x01
#define PRD_DL_K 0xDD
#define PRD_DL_S 0xEE
#define PRD_ALL 0xFF
// Self-Test
#define CMD_SELF_TEST 0xE1
// -- Request
// -- -- --
// -- Response
// -- -- Self-Test Result
#define ST_RSP_LEN 16
#define WD_ST_RET 0x02
#define ST_RET_OK 0xAA
#define ST_RET_ERROR 0x55
#define ST_RET_INFO_LEN 13
// -- -- Signal processor PS voltage
#define WD_SP_FPGA_VOLT 0x03
// -- -- Signal processor PS AUX voltage
#define WD_SP_CLK_STATE 0x04
// -- -- Signal processor DDR voltage
#define WD_SP_AD_LOCK_STATE 0x05
// -- -- Signal processor PL voltage
#define WD_SP_AD_TEMP_0 0x06
// -- -- Signal processor PL AUX voltage
#define WD_SP_AD_TEMP_1 0x07
// -- -- Signal processor Bram voltage
#define WD_SP_FPGA_TEMP 0x08
// Config load
#define CMD_CONFIG 0xE3
// -- Request
#define WD_EN_CMD 0x02
#define EN_CMD_ON_HIGH_POWER 0x66
#define EN_CMD_ON_LOW_POWER 0x77
#define EN_CMD_SILENT 0x88
#define WD_MODE_CMD 0x03
#define MODE_CMD_HEAD 0x11
#define MODE_CMD_MEMBER 0x00
// -- Response
// -- -- none response
// Remote Test
#define RM_TEST_RESP_LEN 158
// -- Request
// Remote Test FLJ
#define CMD_FLJ_RM_TEST 0xE6
// Remote Test LJ
#define CMD_LJ_RM_TEST 0xF6
#define WD_RM_TEST 0x02
#define RM_TEST_CODE 0x99
// -- Response
#define WD_TIME_STAMP 0x02
#define WD_TIME_STAMP_LEN 8
#define WD_SYSBUS_LOG 0x0A
#define WD_SYSBUS_LOG_LEN 14
#define WD_LINK_LOG 0x18
#define WD_LINK_LOG_LEN 64
#define WD_PHY_LOG 0x58
#define WD_PHY_LOG_LEN 57
#define WD_HARDWARE_ST 0x91
#define WD_HARDWARE_ST_LEN 13
// My Production Type
#define MY_PRD_ID PRD_DL_K
/************************** Function Prototypes ******************************/
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
// TODO: better approach?
#include "../networking/link_layer/link_layer.h"
#include "../networking/phy_layer/phy_layer.h"
extern L2_INST *linkInstPtr;
extern L2_CONFIG linkConfig;
inline bool Mpc_IsEnable(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (instPtr->isEnable);
}
inline bool Mpc_IsReqPending(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->rxQueue));
}
inline bool Mpc_IsRsqPending(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->txQueue));
}
inline bool Mpc_IsTxBusy(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!instPtr->isTxDone);
}
inline bool Mpc_IsRxBusy(MPC *instPtr)
{
ASSERT(instPtr != NULL);
return (!instPtr->isRxDone);
}
/**
* @brief Generate System Bus SelfTest response.
*/
static int32_t Mpc_GenSelfTestRsp(MPC *instPtr)
{
ASSERT(instPtr != NULL);
MPC_HW_FRAME *mpcRsp;
uint8_t *msg;
if (Mpc_IsEnable(instPtr) == false)
{
DBG_ERROR("System is not enabled!\n");
return EIGNORE;
}
mpcRsp = malloc(sizeof(MPC_HW_FRAME));
if (mpcRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM;
}
mpcRsp->len = ST_RSP_LEN;
msg = mpcRsp->data + FRAME_PAYLOAD_POFFSET;
HWSTATE *hwStatsPtr = &(instPtr->hwState);
msg[WD_CMD] = CMD_SELF_TEST;
msg[WD_PRD] = MY_PRD_ID;
SysMonitor_GetHardwareStatus(hwStatsPtr);
if (Mpc_IsEnable(instPtr))
{
msg[WD_ST_RET] = (hwStatsPtr->isSpOk && hwStatsPtr->isAntOk) ? ST_RET_OK : ST_RET_ERROR;
}
else
{
msg[WD_ST_RET] = (hwStatsPtr->isSpOk) ? ST_RET_OK : ST_RET_ERROR;
}
// apply status and omit 2 bytes of overhead.
memcpy(msg + WD_SP_FPGA_VOLT, &(hwStatsPtr->spFpgaVolt), ST_RET_INFO_LEN);
if (CircQueuePush(instPtr->txQueue, (void *)mpcRsp) == false)
{
free(mpcRsp);
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
return EQUEUE;
}
return SUCCESS;
}
/**
* @brief Apply system configuration
*/
static int32_t Mpc_SystemConfig(MPC *instPtr, uint8_t *msg)
{
PHY_INST *phyRef = linkInstPtr->config.phyInstPtr;
TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr;
bool reconfig = false;
if (msg[WD_MODE_CMD] == MODE_CMD_HEAD)
{
// omit unnecessary reconfiguration
reconfig = (L2_NODE_HEAD != L2_GetNodeType(linkInstPtr));
linkConfig.myType = L2_NODE_HEAD;
linkConfig.myId = 2;
}
else if (msg[WD_MODE_CMD] == MODE_CMD_MEMBER)
{
// omit unnecessary reconfiguration
reconfig = (L2_NODE_MEMBER != L2_GetNodeType(linkInstPtr));
linkConfig.myType = L2_NODE_MEMBER;
linkConfig.myId = 2;
}
else
{
// Ignore current command
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
WD_MODE_CMD, msg[WD_MODE_CMD]);
return EIGNORE;
}
if (msg[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER)
{
// high power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL);
if (reconfig == true || !Mpc_IsEnable(instPtr))
{
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
Linklayer_Start(linkInstPtr);
instPtr->isEnable = true;
}
else if (msg[WD_EN_CMD] == EN_CMD_ON_LOW_POWER)
{
// low power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW);
if (reconfig == true || !Mpc_IsEnable(instPtr))
{
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
Linklayer_Start(linkInstPtr);
instPtr->isEnable = true;
}
else if (msg[WD_EN_CMD] == EN_CMD_SILENT)
{
// silence config
// TODO: better approach?
instPtr->isEnable = false;
Linklayer_Halt(linkInstPtr);
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_STANDBY);
TIME_WORD pullTime = {0, 0};
pullTime.int_part = TimeCtrl_GetIntCnt(tmcRef) + 1;
if (Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL) != SUCCESS)
{
DBG_ERROR("Physical set pull time failed.\n");
}
Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL);
}
else
{
// Ignore current command
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
WD_EN_CMD, msg[WD_EN_CMD]);
return EIGNORE;
}
instPtr->mpcLog.lastConfig[0] = msg[WD_MODE_CMD];
instPtr->mpcLog.lastConfig[1] = msg[WD_EN_CMD];
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Initialize MPC instance.
*
* @param InstPtr A double pointer to MPC instance.
* @param config A pointer to MPC configurations.
*
* @return Error code.
*
******************************************************************************/
int32_t Mpc_Init(MPC **instPtr, MPC_CONFIG *config)
{
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
MPC_HW_CONFIG mpcHwConfig;
int32_t Status;
(*instPtr) = malloc(sizeof(MPC));
if ((*instPtr) == NULL)
{
return ENOMEM;
}
(*instPtr)->rxQueue = NULL;
(*instPtr)->txQueue = NULL;
(*instPtr)->mpchwDesc = NULL;
memcpy(&((*instPtr)->config), config, sizeof(MPC_CONFIG));
memset(&((*instPtr)->mpcLog), 0x00, sizeof(SYSBUSLOG));
memset(&((*instPtr)->linkLog), 0x00, sizeof(LINKLOG));
memset(&((*instPtr)->phyLog), 0x00, sizeof(PHYLOG));
memset(&((*instPtr)->hwState), 0x00, sizeof(HWSTATE));
XBram_Config *bramConfigPtr;
XBram mpcBram;
bramConfigPtr = XBram_LookupConfig(config->bramId);
if (bramConfigPtr == NULL)
{
Mpc_Destroy(*instPtr);
return EDCONF;
}
Status = XBram_CfgInitialize(&mpcBram, bramConfigPtr,
bramConfigPtr->CtrlBaseAddress);
if (Status != SUCCESS)
{
Mpc_Destroy(*instPtr);
return Status;
}
/*
* Execute the BRAM driver selftest.
*/
Status = XBram_SelfTest(&mpcBram, 0);
if (Status != SUCCESS)
{
Mpc_Destroy(*instPtr);
return Status;
}
mpcHwConfig.txBuffAddr = mpcBram.Config.MemBaseAddress;
mpcHwConfig.rxBuffAddr = mpcBram.Config.MemBaseAddress;
mpcHwConfig.gpioId = config->gpioId;
Status = MpcHw_Init(&((*instPtr)->mpchwDesc), &mpcHwConfig);
if (Status != SUCCESS)
{
Mpc_Destroy(*instPtr);
return ENOMEM;
}
if (CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false)
{
Mpc_Destroy(*instPtr);
return ENOMEM;
}
if (CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false)
{
Mpc_Destroy(*instPtr);
return ENOMEM;
}
(*instPtr)->isEnable = false; // nothing received.
(*instPtr)->isRxDone = false; // nothing received.
(*instPtr)->isTxDone = true; // nothing to be sent.
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Destroy MPC instance.
*
* @param InstPtr A pointer to MPC instance.
*
* @return None.
*
******************************************************************************/
void Mpc_Destroy(MPC *instPtr)
{
if (instPtr == NULL)
{
return;
}
free(instPtr->mpchwDesc);
free(instPtr->txQueue);
free(instPtr->rxQueue);
free(instPtr);
}
/*****************************************************************************/
/**
* @brief Generate a remote test response message.
*
* @param instPtr A pointer to MPC instance.
*
* @return SUCCESS
* error code
*
******************************************************************************/
int32_t Mpc_PendRemoteTest(MPC *instPtr)
{
MPC_HW_FRAME *mpcRsp;
uint8_t *msg;
if (!Mpc_IsEnable(instPtr))
{
DBG_ERROR("System is not enabled!\n");
return EIGNORE;
}
mpcRsp = malloc(sizeof(MPC_HW_FRAME));
if (mpcRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM;
}
msg = mpcRsp->data + FRAME_PAYLOAD_POFFSET;
mpcRsp->len = RM_TEST_RESP_LEN;
if (L2_GetNodeType(linkInstPtr) == L2_NODE_HEAD)
{
// head node config
msg[WD_CMD] = CMD_FLJ_RM_TEST;
}
else
{
msg[WD_CMD] = CMD_LJ_RM_TEST;
}
msg[WD_PRD] = MY_PRD_ID;
TIME_WORD tmWord;
uint64_t time;
TimeCtrl_GetCurrentTime(linkInstPtr->config.tmcInstPtr, &tmWord);
time = (uint64_t)tmWord.int_part * TIME_FRAC_MAX + tmWord.frac_part;
memcpy(msg + WD_TIME_STAMP, &time, WD_TIME_STAMP_LEN);
SysMonitor_GetLinklayerLog(&(instPtr->linkLog));
SysMonitor_GetPhysicalLayerLog(&(instPtr->phyLog));
SysMonitor_GetHardwareStatus(&(instPtr->hwState));
memcpy(msg + WD_SYSBUS_LOG, &(instPtr->mpcLog), WD_SYSBUS_LOG_LEN);
memcpy(msg + WD_LINK_LOG, &(instPtr->linkLog), WD_LINK_LOG_LEN);
memcpy(msg + WD_PHY_LOG, &(instPtr->phyLog), WD_PHY_LOG_LEN);
memcpy(msg + WD_HARDWARE_ST, &(instPtr->hwState.spFpgaVolt), WD_HARDWARE_ST_LEN);
if (CircQueuePush(instPtr->txQueue, (void *)mpcRsp) == false)
{
free(mpcRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
return EQUEUE;
}
instPtr->mpcLog.remoteCnt++;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief A handler function. This handler evaluate the message from system
* bus receive queue, and make appropriate response.
*
* @param instPtr A pointer to MPC instance.
*
* @return None
*
******************************************************************************/
int32_t Mpc_HandleCmd(MPC *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
MPC_HW_FRAME *mpcReq;
uint8_t *reqMsg;
if (CircQueuePop(instPtr->rxQueue, (void **)(&mpcReq)) == false)
{
DBG_WARNING("SystemBus::Nothing to be handled.\n");
return EIGNORE;
}
reqMsg = mpcReq->data + FRAME_PAYLOAD_POFFSET;
if (reqMsg[WD_PRD] != MY_PRD_ID && reqMsg[WD_PRD] != PRD_ALL)
{
DBG_WARNING("SystemBus::Production code mismatch!\n");
return EIGNORE;
}
switch (reqMsg[WD_CMD])
{
case CMD_CONFIG:
{
Status = Mpc_SystemConfig(instPtr, reqMsg);
if (Status == SUCCESS)
{
Status = Mpc_GenSelfTestRsp(instPtr);
}
break;
}
default:
{
DBG_ERROR("SystemBus::Unknown command code!\n");
Status = FAILURE;
break;
}
}
free(mpcReq);
return Status;
}
/*****************************************************************************/
/**
* @brief This function send a repose frame from MPC tx queue.
*
* @param instPtr A pointer to MPC instance.
*
* @return None
*
******************************************************************************/
int32_t Mpc_MakeResp(MPC *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
MPC_HW_FRAME *mpcRsp;
if (CircQueuePop(instPtr->txQueue, (void **)(&mpcRsp)) == false)
{
DBG_WARNING("SystemBus::Nothing to be sent.\n");
return EIGNORE;
}
instPtr->isTxDone = false; // A transmission procedure is started.
Status = MpcHw_Send(instPtr->mpchwDesc, mpcRsp);
free(mpcRsp);
return Status;
}
/*****************************************************************************/
/**
* @brief This function handles the mpc tx irq events.
*
* @param instPtr A pointer to MPC instance.
*
* @return None
*
******************************************************************************/
int32_t Mpc_TxIrqHandler(MPC *instPtr)
{
ASSERT(instPtr != NULL);
// nothing special...
instPtr->isTxDone = true; // A transmission procedure finished.
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief This function handles the mpc rx irq events.
*
* @param instPtr A pointer to MPC instance.
*
* @return None
*
******************************************************************************/
int32_t Mpc_RxIrqHandler(MPC *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
MPC_HW_FRAME *mpcReq;
instPtr->isRxDone = true; // whether reception successes or not, receiving procedure ended.
mpcReq = malloc(sizeof(MPC_HW_FRAME));
if (mpcReq == NULL)
{
return ENOMEM;
}
Status = MpcHw_Recv(instPtr->mpchwDesc, mpcReq);
if (Status != SUCCESS)
{
DBG_ERROR("SystemBus::RX error!\n");
free(mpcReq);
return Status;
}
if (CircQueuePush(instPtr->rxQueue, (void *)mpcReq) == false)
{
DBG_ERROR("SystemBus::RX Queue overflowed!\n");
free(mpcReq);
return EQUEUE;
}
instPtr->isRxDone = false; // another reception is undergoing.
return SUCCESS;
}
+72
View File
@@ -0,0 +1,72 @@
/*****************************************************************************/
/**
* Description: MPC protocol head file.
*
* Date: 2023-05-06 10:12
* Last Edit Time: [2023-05-06 10:13]
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
*
******************************************************************************/
#ifndef __MPC_H_
#define __MPC_H_
/***************************** Include Files *********************************/
#include <stdint.h>
#include <stdbool.h>
#include "mpc_hw.h" // MPC driver
#include "circ_queue.h"
#include "../system_monitor.h"
/************************** Constant Definitions *****************************/
/************************** Data Type Definitions ****************************/
// Definition of MPC instance.
typedef struct
{
uint32_t bramId;
uint32_t gpioId;
uint32_t txQueueMax;
uint32_t rxQueueMax;
} MPC_CONFIG;
typedef struct
{
MPC_CONFIG config;
SYSBUSLOG mpcLog; // mpc log
LINKLOG linkLog; // Link layer log
PHYLOG phyLog; // Physical layer log
HWSTATE hwState; // Hardware status
MPC_HW *mpchwDesc;
CIRC_QUEUE *txQueue;
CIRC_QUEUE *rxQueue;
bool isEnable;
bool isRxDone;
bool isTxDone;
} MPC;
/************************** Function Prototypes ******************************/
int32_t Mpc_Init(MPC **instPtr, MPC_CONFIG *config);
void Mpc_Destroy(MPC *instPtr);
int32_t Mpc_HandleCmd(MPC *instPtr);
int32_t Mpc_PendRemoteTest(MPC *instPtr);
int32_t Mpc_MakeResp(MPC *instPtr);
int32_t Mpc_TxIrqHandler(MPC *instPtr);
int32_t Mpc_RxIrqHandler(MPC *instPtr);
bool Mpc_IsEnable(MPC *instPtr);
bool Mpc_IsReqPending(MPC *instPtr);
bool Mpc_IsRsqPending(MPC *instPtr);
bool Mpc_IsTxBusy(MPC *instPtr);
bool Mpc_IsRxBusy(MPC *instPtr);
#endif //__MPC_H_
+139
View File
@@ -0,0 +1,139 @@
/*****************************************************************************/
/**
* Description: MPC uart driver implementation file.
*
* Date: 2023-05-06 10:59
* LastEditTime: 2023-05-06 21:56
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
*
******************************************************************************/
/***************************** Include Files *******************************/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "mpc_hw.h"
#include "common.h"
// Control and status register
#define MODULE_VERSION 0
#define MPC_STATUS 4
#define MPC_SEND_CMD 8
#define MPC_RECV_CNT 12
// Status code
#define MPC_STATUS_TX_BUSY 0x00010000
#define MPC_STATUS_RX_BUSY 0x01000000
// Data buffer register
#define MPC_TXBUFF_MAX 512
#define MPC_RXBUFF_MAX 512
// Frame Data offsets
#define FRAME_HEAD_LOW 0x02
#define FRAME_HEAD_HIGH 0x53
#define FRAME_TAIL_LOW 0x32
#define FRAME_TAIL_HIGH 0x20
#define FRAME_HEAD_LEN 2
#define FRAME_TAIL_LEN 2
#define FRAME_DUMMY_LEN 1 // Dummy
#define FRAME_OVERHEAD_LEN 2 // CheckSum, Dummy and
#define MPC_STATUS_CH 1
#define MPC_CONFIG_CH 2
#define MPC_CONFIG_SEND_TRIG 0x00000002
/*************************** Function Definitions ****************************/
/*****************************************************************************/
/**
* @brief Instance initial
*
* @param instPtr A pointer to frame uart instance structure.
* @param config Base address of frame uart, refer to "xparameters.h"
*
* @return None.
*
******************************************************************************/
int MpcHw_Init(MPC_HW **instPtr, MPC_HW_CONFIG *config)
{
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
uint32_t Status;
(*instPtr) = malloc(sizeof(MPC_HW));
if ((*instPtr) == NULL)
{
return FAILURE;
}
(*instPtr)->config.txBuffAddr = config->txBuffAddr;
(*instPtr)->config.rxBuffAddr = config->rxBuffAddr;
Status = XGpio_Initialize(&((*instPtr)->gpioDesc), config->gpioId);
if (Status != SUCCESS) {
DBG_ERROR("MPC gpio Initialization Failed.\n");
free(*instPtr);
return FAILURE;
}
XGpio_SetDataDirection(&((*instPtr)->gpioDesc), MPC_CONFIG_CH, 0x00000000);
XGpio_SetDataDirection(&((*instPtr)->gpioDesc), MPC_STATUS_CH, 0xFFFFFFFF);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Send a MPC frame.
*
* @param instPtr A pointer to MPC_HW instance structure.
* @param buff A pointer to send data buffer
* @param dLen A integer indicate the send data buffer length in byte.
*
* @return
*
******************************************************************************/
int MpcHw_Send(MPC_HW *instPtr, MPC_HW_FRAME *frame)
{
ASSERT(instPtr != NULL);
ASSERT(frame != NULL);
uint8_t sendLen;
uint8_t *sendBuff = (uint8_t*) instPtr->config.txBuffAddr;
sendLen = frame->len + FRAME_OVERHEAD_LEN;
if (sendLen > MPC_TXBUFF_MAX || frame->len == 0)
{
return FAILURE;
}
frame->data[0] = FRAME_HEAD_LOW;
frame->data[1] = FRAME_HEAD_HIGH;
memcpy(sendBuff, frame->data, sendLen);
// Start Sending
uint32_t gpioVal = XGpio_DiscreteRead(&(instPtr->gpioDesc), MPC_CONFIG_CH);
gpioVal ^= MPC_CONFIG_SEND_TRIG;
XGpio_DiscreteWrite(&(instPtr->gpioDesc), MPC_CONFIG_CH, gpioVal);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Get last MPC frame.
*
* @param instPtr A pointer to MPC_HW instance structure.
* @param buff A pointer to receive data buffer.
*
* @return
*
******************************************************************************/
int MpcHw_Recv(MPC_HW *instPtr, MPC_HW_FRAME *frame)
{
ASSERT(instPtr != NULL);
ASSERT(frame != NULL);
uint8_t *recvBuff = (uint8_t *)(instPtr->config.rxBuffAddr);
memcpy(frame->data, recvBuff, MPC_FRAME_MAX);
frame->len = MPC_FRAME_MAX;
frame->isValid = true;
return SUCCESS;
}
+98
View File
@@ -0,0 +1,98 @@
/*****************************************************************************/
/**
* Description: MPC uart driver implementation file.
*
* Date: 2023-05-06 10:59
* LastEditTime: 2023-05-06 21:48
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
*
******************************************************************************/
#ifndef __MPC_HW_H
#define __MPC_HW_H
/**************************** Include Files *****************************/
#include <stdint.h>
#include <stdbool.h>
#include "util.h"
#include "xgpio.h"
#define MPC_FRAME_MAX 256
#define FRAME_PAYLOAD_POFFSET 2 // CheckSum, Dummy and DataLen
/**************************** Type Definitions *****************************/
/**
*
* Write a value to a SYSTEMBUS_UART register. A 32 bit write is performed.
* If the component is implemented in a smaller width, only the least
* significant data is written.
*
* @param baseAddr is the base address of the SYSTEMBUS_UARTdevice.
* @param offset is the register offset from the base to write to.
* @param data is the data written to the register.
*
* @return None.
*
* @note
* C-style signature:
* void MPC_HW_mWriteReg(uint32_t BaseAddress, unsigned RegOffset, uint32_t Data)
*
*/
#define MPC_HW_mWriteReg(baseAddr, offset, data) \
IO_Out32((baseAddr) + (offset), (uint32_t)(data))
/**
*
* Read a value from a SYSTEMBUS_UART register. A 32 bit read is performed.
* If the component is implemented in a smaller width, only the least
* significant data is read from the register. The most significant data
* will be read as 0.
*
* @param baseAddr is the base address of the SYSTEMBUS_UART device.
* @param offset is the register offset from the base to write to.
*
* @return Data is the data from the register.
*
* @note
* C-style signature:
* uint32_t MPC_HW_mReadReg(uint32_t BaseAddress, unsigned RegOffset)
*
*/
#define MPC_HW_mReadReg(baseAddr, offset) \
IO_In32((baseAddr) + (offset))
typedef struct
{
uintptr_t txBuffAddr;
uintptr_t rxBuffAddr;
uint32_t gpioId;
} MPC_HW_CONFIG;
typedef struct
{
MPC_HW_CONFIG config;
XGpio gpioDesc;
} MPC_HW;
typedef struct
{
uint16_t len;
uint8_t checkSum;
uint8_t isValid;
uint8_t data[MPC_FRAME_MAX];
} MPC_HW_FRAME;
/************************** Function Prototypes ******************************/
// Instance initial
int MpcHw_Init(MPC_HW **instPtr, MPC_HW_CONFIG *config);
// Send a MPC frame.
int MpcHw_Send(MPC_HW *instPtr, MPC_HW_FRAME *frame);
// Get last MPC frame.
int MpcHw_Recv(MPC_HW *instPtr, MPC_HW_FRAME *frame);
#endif // __MPC_HW_H
-1
View File
@@ -1 +0,0 @@
../../df_datalink_sp/src/systembus
@@ -24,7 +24,7 @@
/* Definitions for interface TMC */
#define XPAR_TMC_BASEADDR 0x43C30000
#define XPAR_TMC_HIGHADDR 0x43C3FFFF
#define XPAR_TMC_HIGHADDR 0x43C30FFF
#include "xparameters_ps.h"
@@ -42,28 +42,46 @@
/******************************************************************/
/* Definitions for driver BRAM */
#define XPAR_XBRAM_NUM_INSTANCES 3U
#define XPAR_XBRAM_NUM_INSTANCES 4U
/* Definitions for peripheral PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL */
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DATA_WIDTH 32U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_FAULT_INJECT 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_FAILING_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_UE_FAILING_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_STATUS_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_COUNTER_WIDTH 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_REGISTER 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_WRITE_ACCESS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_BASEADDR 0x40004000U
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_HIGHADDR 0x40005FFFU
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU
/* Definitions for peripheral PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL */
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DEVICE_ID 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DATA_WIDTH 32U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_ECC 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_FAULT_INJECT 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_CE_FAILING_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_UE_FAILING_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_ECC_STATUS_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_CE_COUNTER_WIDTH 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_ECC_ONOFF_REGISTER 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_WRITE_ACCESS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_BASEADDR 0x42000000U
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_HIGHADDR 0x42000FFFU
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU
/* Definitions for peripheral PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL */
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID 1U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DATA_WIDTH 32U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_FAULT_INJECT 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_CE_FAILING_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_UE_FAILING_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_STATUS_REGISTERS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_CE_COUNTER_WIDTH 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_ONOFF_REGISTER 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_WRITE_ACCESS 0U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_BASEADDR 0x40004000U
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_HIGHADDR 0x40005FFFU
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU
/* Definitions for peripheral PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL */
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID 1U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID 2U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DATA_WIDTH 32U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC 0U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_FAULT_INJECT 0U
@@ -75,13 +93,13 @@
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_WRITE_ACCESS 0U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_BASEADDR 0x40000000U
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x40001FFFU
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x40000FFFU
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU
/* Definitions for peripheral PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL */
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID 2U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID 3U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DATA_WIDTH 32U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC 0U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_FAULT_INJECT 0U
@@ -93,15 +111,15 @@
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_WRITE_ACCESS 0U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_BASEADDR 0x40002000U
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x40003FFFU
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_HIGHADDR 0x40002FFFU
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_S_AXI_CTRL_HIGHADDR 0xFFFFFFFFU
/******************************************************************/
/* Canonical definitions for peripheral PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL */
#define XPAR_BRAM_0_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID
/* Canonical definitions for peripheral PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL */
#define XPAR_BRAM_0_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DEVICE_ID
#define XPAR_BRAM_0_DATA_WIDTH 32U
#define XPAR_BRAM_0_ECC 0U
#define XPAR_BRAM_0_FAULT_INJECT 0U
@@ -112,13 +130,13 @@
#define XPAR_BRAM_0_ECC_ONOFF_REGISTER 0U
#define XPAR_BRAM_0_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_BRAM_0_WRITE_ACCESS 0U
#define XPAR_BRAM_0_BASEADDR 0x40004000U
#define XPAR_BRAM_0_HIGHADDR 0x40005FFFU
#define XPAR_BRAM_0_BASEADDR 0x42000000U
#define XPAR_BRAM_0_HIGHADDR 0x42000FFFU
#define XPAR_BRAM_0_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_BRAM_0_CTRL_HIGHADDR 0xFFFFFFFEU
/* Canonical definitions for peripheral PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL */
#define XPAR_BRAM_1_DEVICE_ID XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID
/* Canonical definitions for peripheral PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL */
#define XPAR_BRAM_1_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID
#define XPAR_BRAM_1_DATA_WIDTH 32U
#define XPAR_BRAM_1_ECC 0U
#define XPAR_BRAM_1_FAULT_INJECT 0U
@@ -129,13 +147,13 @@
#define XPAR_BRAM_1_ECC_ONOFF_REGISTER 0U
#define XPAR_BRAM_1_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_BRAM_1_WRITE_ACCESS 0U
#define XPAR_BRAM_1_BASEADDR 0x40000000U
#define XPAR_BRAM_1_HIGHADDR 0x40001FFFU
#define XPAR_BRAM_1_BASEADDR 0x40004000U
#define XPAR_BRAM_1_HIGHADDR 0x40005FFFU
#define XPAR_BRAM_1_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_BRAM_1_CTRL_HIGHADDR 0xFFFFFFFEU
/* Canonical definitions for peripheral PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL */
#define XPAR_BRAM_2_DEVICE_ID XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID
/* Canonical definitions for peripheral PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL */
#define XPAR_BRAM_2_DEVICE_ID XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID
#define XPAR_BRAM_2_DATA_WIDTH 32U
#define XPAR_BRAM_2_ECC 0U
#define XPAR_BRAM_2_FAULT_INJECT 0U
@@ -146,11 +164,28 @@
#define XPAR_BRAM_2_ECC_ONOFF_REGISTER 0U
#define XPAR_BRAM_2_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_BRAM_2_WRITE_ACCESS 0U
#define XPAR_BRAM_2_BASEADDR 0x40002000U
#define XPAR_BRAM_2_HIGHADDR 0x40003FFFU
#define XPAR_BRAM_2_BASEADDR 0x40000000U
#define XPAR_BRAM_2_HIGHADDR 0x40000FFFU
#define XPAR_BRAM_2_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_BRAM_2_CTRL_HIGHADDR 0xFFFFFFFEU
/* Canonical definitions for peripheral PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL */
#define XPAR_BRAM_3_DEVICE_ID XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID
#define XPAR_BRAM_3_DATA_WIDTH 32U
#define XPAR_BRAM_3_ECC 0U
#define XPAR_BRAM_3_FAULT_INJECT 0U
#define XPAR_BRAM_3_CE_FAILING_REGISTERS 0U
#define XPAR_BRAM_3_UE_FAILING_REGISTERS 0U
#define XPAR_BRAM_3_ECC_STATUS_REGISTERS 0U
#define XPAR_BRAM_3_CE_COUNTER_WIDTH 0U
#define XPAR_BRAM_3_ECC_ONOFF_REGISTER 0U
#define XPAR_BRAM_3_ECC_ONOFF_RESET_VALUE 0U
#define XPAR_BRAM_3_WRITE_ACCESS 0U
#define XPAR_BRAM_3_BASEADDR 0x40002000U
#define XPAR_BRAM_3_HIGHADDR 0x40002FFFU
#define XPAR_BRAM_3_CTRL_BASEADDR 0xFFFFFFFFU
#define XPAR_BRAM_3_CTRL_HIGHADDR 0xFFFFFFFEU
/******************************************************************/
@@ -311,7 +346,7 @@
/* Definitions for peripheral SYSTEMBUS */
#define XPAR_SYSTEMBUS_BASEADDR 0x43C10000
#define XPAR_SYSTEMBUS_HIGHADDR 0x43C11FFF
#define XPAR_SYSTEMBUS_HIGHADDR 0x43C10FFF
/******************************************************************/
@@ -43,23 +43,42 @@
XBram_Config XBram_ConfigTable[] =
{
{
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DATA_WIDTH,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_FAULT_INJECT,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_FAILING_REGISTERS,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DEVICE_ID,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DATA_WIDTH,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_ECC,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_FAULT_INJECT,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_CE_FAILING_REGISTERS,
0,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_UE_FAILING_REGISTERS,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_UE_FAILING_REGISTERS,
0,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_STATUS_REGISTERS,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_CE_COUNTER_WIDTH,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_REGISTER,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_ECC_ONOFF_RESET_VALUE,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_WRITE_ACCESS,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_BASEADDR,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_HIGHADDR,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_BASEADDR,
XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_S_AXI_CTRL_HIGHADDR
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_ECC_STATUS_REGISTERS,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_CE_COUNTER_WIDTH,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_ECC_ONOFF_REGISTER,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_ECC_ONOFF_RESET_VALUE,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_WRITE_ACCESS,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_BASEADDR,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_HIGHADDR,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_CTRL_BASEADDR,
XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_S_AXI_CTRL_HIGHADDR
},
{
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DATA_WIDTH,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_FAULT_INJECT,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_CE_FAILING_REGISTERS,
0,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_UE_FAILING_REGISTERS,
0,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_STATUS_REGISTERS,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_CE_COUNTER_WIDTH,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_ONOFF_REGISTER,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_ECC_ONOFF_RESET_VALUE,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_WRITE_ACCESS,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_BASEADDR,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_HIGHADDR,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_CTRL_BASEADDR,
XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_S_AXI_CTRL_HIGHADDR
},
{
XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID,
+7 -1
View File
@@ -27,7 +27,13 @@ END
BEGIN DRIVER
PARAMETER DRIVER_NAME = bram
PARAMETER DRIVER_VER = 4.3
PARAMETER HW_INSTANCE = phy_data_interface_ant_info_bram_ctrl
PARAMETER HW_INSTANCE = phy_data_interface_ant_beam_bram_ctrl
END
BEGIN DRIVER
PARAMETER DRIVER_NAME = bram
PARAMETER DRIVER_VER = 4.3
PARAMETER HW_INSTANCE = phy_data_interface_ant_config_bram_ctrl
END
BEGIN DRIVER
@@ -32,7 +32,7 @@ C_DEPS += \
src/dev_profile/%.o: ../src/dev_profile/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
@@ -23,7 +23,7 @@ C_DEPS += \
src/networking/link_layer/geometry/%.o: ../src/networking/link_layer/geometry/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
@@ -38,7 +38,7 @@ C_DEPS += \
src/networking/link_layer/%.o: ../src/networking/link_layer/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
@@ -20,7 +20,7 @@ C_DEPS += \
src/networking/phy_layer/%.o: ../src/networking/phy_layer/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
+7 -4
View File
@@ -8,22 +8,25 @@ LD_SRCS += \
C_SRCS += \
../src/main.c \
../src/system_monitor.c
../src/system_monitor.c \
../src/hwconfig.c
OBJS += \
./src/main.o \
./src/system_monitor.o
./src/system_monitor.o \
./src/hwconfig.o
C_DEPS += \
./src/main.d \
./src/system_monitor.d
./src/system_monitor.d \
./src/hwconfig.d
# Each subdirectory must supply rules for building sources it contributes
src/%.o: ../src/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
+1 -1
View File
@@ -20,7 +20,7 @@ C_DEPS += \
src/systembus/%.o: ../src/systembus/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
+1 -1
View File
@@ -17,7 +17,7 @@ C_DEPS += \
src/time_ctrl/%.o: ../src/time_ctrl/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
arm-none-eabi-gcc -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
arm-none-eabi-gcc -std=c17 -pedantic -Wall -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
+1 -1
View File
@@ -32,7 +32,7 @@ C_DEPS += \
src/util/%.o: ../src/util/%.c
@echo 'Building file: $<'
@echo 'Invoking: ARM v7 gcc compiler'
$(CC) -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
$(CC) -std=c17 -pedantic -Wall -Wformat=2 -O0 -g3 -I../bsp/ps7_cortexa9_0/include -I../src/include -c -fmessage-length=0 -MT"$@" -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '
+4 -8
View File
@@ -10,7 +10,7 @@
* History:
* [2021-04-28]: Initial edition.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Copyright(c) 2024 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
@@ -52,12 +52,12 @@
#define SCUTIMER_INTR_ID XPAR_SCUTIMER_INTR
// Physical Layer Configs
#define PHY_DEVICE_ID 0
#define PHY_DEVICE_ID 0X00
#define PHY_BASEADDR XPAR_PHYC_BASEADDR
#define PHY_BEAM_SET_PRESET
#define PHY_BEAM_FORMING_ENABLE
// -- Antenna Bram Configs
#define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_INFO_BRAM_CTRL_DEVICE_ID
#define PHY_ANTCONFIG_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_CONFIG_BRAM_CTRL_DEVICE_ID
#define PHY_ANTINFO_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_ANT_BEAM_BRAM_CTRL_DEVICE_ID
// -- Buffers
#define PHY_TXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_TX_FRAME_BRAM_CTRL_DEVICE_ID
#define PHY_RXBUFF_BRAM_DEVICE_ID XPAR_PHY_DATA_INTERFACE_RX_FRAME_BRAM_CTRL_DEVICE_ID
@@ -179,7 +179,6 @@ typedef enum
#define HMC7044_SPI_ENGINE_CS_DELAY 3
#define HMC7044_SPI_CS_HMC7044 0x00
// Configuration Check
#if defined(PHY_BEAM_SET_PRESET) && !defined(PHY_BEAM_FORMING_ENABLE)
#define PHY_BEAM_FORMING_ENABLE
@@ -190,9 +189,6 @@ typedef enum
#if !defined(DATALINK_ENABLE_AUTOTIMESYNC)
#warning To enbale bit error rate test, auto time-sync should be enabled...
#endif
#if defined(DATALINK_ENABLE_AUTORECONNECT)
#error Do not support auto reconnnect in bit error rate test mode...
#endif
#endif
#endif //__APP_CONFIG_H_
@@ -697,7 +697,6 @@ int32_t spi_engine_write_and_read(struct spi_desc *desc,
uint8_t *data,
uint16_t bytes_number)
{
uint8_t i;
uint8_t word_len;
uint8_t words_number;
int32_t ret;
+474
View File
@@ -0,0 +1,474 @@
/*****************************************************************************/
/**
* 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 **************************/
static struct hmc7044_dev *hmc7044_inst = NULL;
static struct ad9361_reg_dev *ad9361_1_reg_inst = NULL;
static struct ad9361_reg_dev *ad9361_2_reg_inst = NULL;
// 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(AD9361_GPIO_DEVICE_ID);
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
if (Status != SUCCESS)
{
return FAILURE;
}
/**********************************************************/
/****************** HMC7044 Configuration *****************/
/**********************************************************/
Status = hmc7044_init(&hmc7044_inst, &hmc7044_default_init_param);
if (Status != SUCCESS)
{
DBG_ERROR("hmc7044_init() error: %" PRId32 "\n", Status);
return FAILURE;
}
/**********************************************************/
/***************** 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_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_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);
/**********************************************************/
/******* AD9361 Baseband Multichip Synchronization ********/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_SYNC, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_RX_FIFO_RST, AD9361_GPIO_OUTPUT);
// SYNC BBPLL and DIGITAL SAMPLING CLOCKS
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0D); // MCS RF Enable; MCS BBPLL Enable; MCS BB Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0D);
ad9361_reg_write(ad9361_1_reg_inst, 0x0047, 0x80); // MCS refclk Scale Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0047, 0x80);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0);
mdelay(20);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input a rising-edge pulse to the SYNC_IN pin
mdelay(500);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0);
mdelay(2000);
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0B); // MCS RF Enable; MCS Digital CLK Enable ; MCS BB Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0B);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input another rising-edge pulse to the SYNC_IN pin
mdelay(500);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0);
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x08); // clear MCS bits
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x08);
XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0);
mdelay(20);
XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 1);
mdelay(20);
XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0);
/**********************************************************/
/********* AD9361 Multichip Rx Phase Calibration **********/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_TX_SWITCH, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_START, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_DONE, AD9361_GPIO_INPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_START, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_DONE, AD9361_GPIO_INPUT);
// switch to lower frequency
Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_126);
XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 1);
mdelay(20);
// switch rx channel
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x30);
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x30);
// enable dual ad9361 tx channels
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xE4); // Setup Tx Digital Filters/ Channels
// switch ad9361 tx channel
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x70); // Select Rx input pin(A,B,C)/ Tx out pin (A,B)
mdelay(20);
// begin to calibrate the 1st ad9361
XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0);
XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 1);
mdelay(1);
XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0);
// read calibration status
int32_t time_out_cnt = 0;
do
{
mdelay(1); // Wait 1ms
time_out_cnt++;
} while (((XGpioPs_ReadPin(&Gpio, AD9361_1_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH));
if (time_out_cnt == AD9361_TIMEOUT_TH)
{
return FAILURE;
}
// begin to calibrate the 2nd ad9361
XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 1);
mdelay(1);
XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 0);
// read calibration status
time_out_cnt = 0;
do
{
mdelay(1); // Wait 1ms
time_out_cnt++;
} while (((XGpioPs_ReadPin(&Gpio, AD9361_2_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH));
if (time_out_cnt == AD9361_TIMEOUT_TH)
{
return FAILURE;
}
// enable single ad9361 tx channels
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xA4); // Setup Tx Digital Filters/ Channels
// switch ad9361 tx & rx channel
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x03);
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x03);
// switch to higher frequency
Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_4125);
XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 0);
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
DBG_PRINT("Done.\n");
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Hardware_SwitchFreq
*
* @param devSysMonitor_UpdateHardwareStatus(newHwState);
* @param freq
*
* @return None.
*
******************************************************************************/
int32_t Hardware_SwitchFreq(struct ad9361_reg_dev *dev, ad9361TxFreq freq)
{
int32_t status = 0;
uint8_t value = 0;
int32_t time_out_cnt = 0;
switch (freq)
{
case TX_FREQ_125:
{
//************************************************************
// Setup Tx Frequency-Dependent Syntheisizer Registers
//************************************************************
status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0]
status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0]
status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0]
status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0]
status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0]
status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0]
status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0]
status = ad9361_reg_write(dev, 0x027B, 0x94); // Set Synth Loop Filter charge pump current (Icp)
status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1
status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3
status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3
//************************************************************
// Write Tx Frequency Words
//************************************************************
status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0]
status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8]
status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16]
status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8]
status = ad9361_reg_write(dev, 0x0271, 0xA0); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal)
status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting
//************************************************************
// Tx Quadrature Calibration Settings
//************************************************************
status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency
status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6])
status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable
status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count
status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp
status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index
status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count
status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used
status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration
status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal
break;
}
case TX_FREQ_126:
{
//************************************************************
// Setup Tx Frequency-Dependent Syntheisizer Registers
//************************************************************
status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0]
status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0]
status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0]
status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0]
status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0]
status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0]
status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0]
status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp)
status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1
status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3
status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3
//************************************************************
// Write Tx Frequency Words
//************************************************************
status = ad9361_reg_write(dev, 0x0273, 0x06); // Write Tx Synth Fractional Freq Word[7:0]
status = ad9361_reg_write(dev, 0x0274, 0xD7); // Write Tx Synth Fractional Freq Word[15:8]
status = ad9361_reg_write(dev, 0x0275, 0x23); // Write Tx Synth Fractional Freq Word[22:16]
status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8]
status = ad9361_reg_write(dev, 0x0271, 0xA1); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal)
status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting
//************************************************************
// Tx Quadrature Calibration Settings
//************************************************************
status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency
status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6])
status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable
status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count
status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp
status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index
status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count
status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used
status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration
status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal
break;
}
case TX_FREQ_4125:
{
//************************************************************
// Setup Tx Frequency-Dependent Syntheisizer Registers
//************************************************************
status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0]
status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0]
status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0]
status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0]
status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0]
status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0]
status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0]
status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp)
status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1
status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3
status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3
//************************************************************
// Write Rx Frequency Words
//************************************************************
status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0]
status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8]
status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16]
status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8]
status = ad9361_reg_write(dev, 0x0271, 0xA5); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal)
status = ad9361_reg_write(dev, 0x0005, 0x07); // Set LO divider setting
//************************************************************
// Tx Quadrature Calibration Settings
//************************************************************
status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency
status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6])
status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable
status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count
status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp
status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00AA, 0x28); // Set Tx Quad Cal Gain Table index
status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count
status = ad9361_reg_write(dev, 0x00AE, 0x04); // Set Tx Quad Cal LPF Gain index incase Split table mode used
status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration
status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal
break;
}
// Wait for cal to complete (Done when 0x016[4]==0)
time_out_cnt = 0;
do
{
status |= ad9361_reg_read(dev, 0x0016, &value);
mdelay(1); // Wait 1ms
time_out_cnt++;
} while ((value & 0x10) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH);
}
return status;
}
// @ 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 HMC7044 lock state
/**
* Read corresponding register to determine clock lock state.
*/
uint8_t Hardware_GetHMC7044LockStatus(void)
{
uint8_t ret = 0;
uint8_t regVal;
// pll1
hmc7044_read(hmc7044_inst, 0x007C, &regVal); // [D5] is lock indicator
ret |= ((regVal & 0xE0) != 0x00) ? CLK_SP_PLL0_LOCK : 0;
// pll2
hmc7044_read(hmc7044_inst, 0x007D, &regVal); // [D0] is lock indicator
ret |= ((regVal & 0x01) == 0x01) ? CLK_SP_PLL1_LOCK : 0;
return ret;
}
+33
View File
@@ -0,0 +1,33 @@
/*****************************************************************************/
/**
* 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.
*
******************************************************************************/
#ifndef HWCONFIG_H_
#define HWCONFIG_H_
/***************************** 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_GetHMC7044LockStatus(void);
#endif // HWCONFIG_H_
+43 -54
View File
@@ -1,34 +1,26 @@
/*****************************************************************************/
/**
* Description: A simple circular FIFO bounded queue
* @file circ_queue.h
* @author FanHao ([email protected])
* @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
*
* Author: Fan Hao
* Date: 2023-02-23 10:29
* LastEditors: Fan Hao
* LastEditTime: 2023-02-23 12:53
* Revisions: Rev 0.0
* History:
* [2023-02-23]: Initial Version.
*
* Copyright(c) 2023 Beijing Institute of Technology.
* Lab of Communication and Networking
* NOTE: Forked from https://github.com/chrismerck/rpa_queue.git
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
/**
* @defgroup CircularQueue
* @{
*/
#ifndef CIRC_QUEUE_H
#define CIRC_QUEUE_H
@@ -36,76 +28,73 @@
#include <stdint.h>
#include <stddef.h>
/**
* opaque structure
* @struct CIRC_QUEUE
* @brief Circular queue Instance
*/
typedef struct {
typedef struct
{
void **data;
volatile uint32_t nelts; /**< # elements */
uint32_t in; /**< next empty location */
uint32_t out; /**< next filled location */
uint32_t bounds;/**< max size of queue */
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;
/**
* create a FIFO queue
* @brief create a FIFO queue
* @param queue The new queue
* @param queue_capacity maximum size of the queue
* @param a pool to allocate queue from
*/
bool CircQueueCreate(CIRC_QUEUE **queue, uint32_t queue_capacity);
/** free queue memory -- call after destroy
* @note we do not free in destroy() to follow pthreads convention
/**
* @brief free queue memory -- call after destroy
*/
void CircQueueFree(CIRC_QUEUE *queue);
/**
* Detects when the CIRC_QUEUE is full. This utility function is expected
* @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);
/**
* Detects when the CIRC_QUEUE is empty. This utility function is expected
* @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);
/**
* push/add an object to the queue, blocking if the queue is already full
* @brief push/add an object to the queue, blocking if the queue is already full
*
* @param queue the queue
* @param data the data
* @returns RPA_EINTR the blocking was interrupted (try again)
* @returns RPA_EOF the queue has been terminated
* @returns RPA_SUCCESS on a successful push
* @return True on a successful push
* @return False push failed
*/
bool CircQueuePush(CIRC_QUEUE *queue, void *data);
/**
* pop/get an object from the queue, blocking if the queue is already empty
* @brief pop/get an object from the queue, blocking if the queue is already empty
*
* @param queue the queue
* @param data the data
* @returns RPA_EINTR the blocking was interrupted (try again)
* @returns RPA_EOF if the queue has been terminated
* @returns RPA_SUCCESS on a successful pop
* @return false pop failed
* @return true on a successful pop
*/
bool CircQueuePop(CIRC_QUEUE *queue, void **data);
/**
* returns the size of the queue.
* @brief returns the size of the queue.
*
* @warning this is not threadsafe, and is intended for reporting/monitoring
* of the queue.
* @param queue the queue
* @returns the size of the queue
* @return the size of the queue
*/
uint32_t CircQueueSize(CIRC_QUEUE *queue);
#endif /* CIRC_QUEUE_H */
/** @} CircularQueue*/
/** @} Utility*/
+46 -26
View File
@@ -1,9 +1,25 @@
/*****************************************************************************/
/**
* @file clist.h
* @author FanHao ([email protected])
* @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
*
******************************************************************************/
//
// clist.h
//
// Copyright (c) 2010 TJ Holowaychuk <[email protected]>
//
/**
* @addtogroup Utility
* @{
*/
/**
* @defgroup cList
* @{
*/
#ifndef __CLIST_H__
#define __CLIST_H__
@@ -16,48 +32,48 @@ extern "C"
#include <stdlib.h>
#include <stdint.h>
/*
* clist_t iterator direction.
/**
* @enum clist_direction_t
* @brief clist_t iterator direction.
*/
typedef enum
{
LIST_HEAD,
LIST_TAIL
} clist_direction_t;
/*
* clist_t node struct.
/**
* @struct clist_node_t
* @brief clist_t node struct.
*/
typedef struct clist_node
{
struct clist_node *prev;
struct clist_node *next;
struct clist_node *prev; ///< previous node
struct clist_node *next; ///< next node
void *val;
} clist_node_t;
/*
* clist_t struct.
/**
* @struct clist_t
* @brief clist_t struct.
*/
typedef struct
{
clist_node_t *head;
clist_node_t *tail;
uint32_t len;
void (*free)(void *val);
int8_t (*compare)(void *a, void *b);
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;
/*
* clist_t iterator struct.
/**
* @struct clist_iterator_t
* @brief clist_t iterator struct.
*/
typedef struct
{
clist_node_t *next;
clist_direction_t direction;
clist_node_t *next; ///< next element
clist_direction_t direction; ///< iter direction
} clist_iterator_t;
// Node prototypes.
@@ -116,3 +132,7 @@ extern "C"
#endif
#endif /* __CLIBS_LIST_H__ */
/** @} cList*/
/** @} Utility*/
+14 -13
View File
@@ -1,20 +1,19 @@
/*****************************************************************************/
/**
* Description: Common definitions
*
* Date: 2023-12-21 16:32
* LastEditors: Fan Hao
* LastEditTime: 2022-07-16 17:13
* Revisions: Rev 0.1
* History:
* [2023-12-21]: Ensure the code conform ISO C11 standard.
* [2022-07-16]: New branch for Dijian.
* [2021-11-16]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @file common.h
* @author FanHao ([email protected])
* @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_
@@ -90,3 +89,5 @@
/************************** Function Prototypes ******************************/
void AppAssert(const char *file, int line);
#endif /* __COMMON_H_ */
/** @} */
+21 -12
View File
@@ -1,20 +1,20 @@
/*****************************************************************************/
/**
* Description: Error code definitions.
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:12
* Revisions: Rev 0.0
* History:
* [2022-06-18]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
* @file common.h
* @author FanHao ([email protected])
* @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_
@@ -24,6 +24,11 @@
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
/**
* @name ERRORNO
* @{
*/
#ifdef SUCCESS
#undef SUCCESS
#endif
@@ -45,3 +50,7 @@
#define IS_ERR_VALUE(x) ((x) != SUCCESS)
#endif // ERROR_H_
/** @} ERRORNO*/
/** @} COMMON_MACRO*/
+17 -35
View File
@@ -1,41 +1,21 @@
/*******************************************************************************
/*****************************************************************************/
/**
* @file util.h
* @brief Implementation of utility functions.
* @author DBogdan ([email protected])
********************************************************************************
* Copyright 2018(c) Analog Devices, Inc.
* @author FanHao ([email protected])
* @brief Utility functions header file
* @version 0.0
* @date 2023-05-06
*
* All rights reserved.
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
* 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.
*******************************************************************************/
******************************************************************************/
/**
* @defgroup Utility
* @{
*/
#ifndef __UTIL_H_
#define __UTIL_H_
@@ -193,3 +173,5 @@ bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_
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_
/** @} */
+4 -3
View File
@@ -23,9 +23,10 @@ _UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
MEMORY
{
phy_data_interface_rx_frame_bram_ctrl_Mem0 : ORIGIN = 0x40000000, LENGTH = 0x2000
phy_data_interface_tx_frame_bram_ctrl_Mem0 : ORIGIN = 0x40002000, LENGTH = 0x2000
phy_data_interface_ant_info_bram_ctrl_Mem0 : ORIGIN = 0x40004000, LENGTH = 0x2000
phy_data_interface_rx_frame_bram_ctrl_Mem0 : ORIGIN = 0x40000000, LENGTH = 0x1000
phy_data_interface_tx_frame_bram_ctrl_Mem0 : ORIGIN = 0x40002000, LENGTH = 0x1000
phy_data_interface_ant_config_bram_ctrl_Mem0 : ORIGIN = 0x40004000, LENGTH = 0x2000
phy_data_interface_ant_beam_bram_ctrl_Mem0 : ORIGIN = 0x42000000, LENGTH = 0x1000
ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x1FF00000
ps7_qspi_linear_0 : ORIGIN = 0xFC000000, LENGTH = 0x1000000
ps7_ram_0 : ORIGIN = 0x0, LENGTH = 0x30000
+38 -386
View File
@@ -10,7 +10,7 @@
* History:
* [2023-05-07]: Initial edition.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Copyright(c) 2024 Beijing Institute of Technology.
*
******************************************************************************/
@@ -20,19 +20,15 @@
#include <stdint.h>
#include <stdbool.h>
// Xilinx
#include "sleep.h"
#include "xil_cache.h"
#include "xscugic.h"
#include "xscutimer.h"
#include "xgpiops.h"
#include "drivers/platform/xilinx_irq.h"
#include "drivers/platform/xilinx_timer.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 "timer.h"
#include "hwconfig.h"
#include "system_monitor.h"
#include "config/app_config.h"
#include "dev_profile/dev_profile.h"
#include "systembus/systembus.h"
@@ -46,6 +42,7 @@ void PeriodicPull_Handler(void *callBackRef);
void ScuTimer_IntrHandler(void *context);
void Systembus_RxIntrHandler(void *context);
void Systembus_TxIntrHandler(void *context);
/************************** Constant Definitions *****************************/
struct callback_desc phy_callback_desc = {
.callback = Phy_IntrHandler,
@@ -75,58 +72,57 @@ struct callback_desc scutm_callback_desc = {
L2_CONFIG linkConfig = {
.myType = L2_NODE_HEAD,
.clustId = 1,
.myId = 1,
.headId = 1,
.bkpHeadId = 0,
.netScale = 2,
.clustId = 1U,
.myId = 1U,
.headId = 1U,
.netScale = 2U,
.phyInstPtr = NULL, // physical layer reference
.tmcInstPtr = NULL
};
// L2_CONFIG linkConfig = {
// .myType = L2_NODE_MEMBER,
// .clustId = 1,
// .myId = 2,
// .headId = 1,
// .bkpHeadId = 0,
// .netScale = 2,
// .clustId = 1U,
// .myId = 2U,
// .headId = 1U,
// .netScale = 2U,
// .phyInstPtr = NULL, // physical layer reference
// .tmcInstPtr = NULL
// };
static PHY_CONFIG phyConfig = {
.devId = 0,
.devId = PHY_DEVICE_ID,
.baseAddr = PHY_BASEADDR,
.antBramId = PHY_ANTCONFIG_BRAM_DEVICE_ID,
.antInfoBramId = PHY_ANTINFO_BRAM_DEVICE_ID,
.txBramId = PHY_TXBUFF_BRAM_DEVICE_ID,
.rxBramId = PHY_RXBUFF_BRAM_DEVICE_ID,
.hwXadcId = PHY_HW_XADC_DEVICE_ID
.hwXadcId = PHY_HW_XADC_DEVICE_ID,
.get_clk_state = Hardware_GetHMC7044LockStatus,
.get_ad_lock_state = Hardware_GetAD9361LockStatus,
.get_ad0_temp = Hardware_GetAD9361Temp_1,
.get_ad1_temp = Hardware_GetAD9361Temp_2
};
TMC_CONFIG tmcConfig = {
.baseAddr = TIME_CONTROLLER_BASEADDR,
.reset = 10
.reset = 10U
};
static SYSBUS_CONFIG sysbusConfig = {
.baseAddr = SYSBUS_BASE_ADDR,
.txQueueMax = 16,
.rxQueueMax = 16
.txQueueMax = 16U,
.rxQueueMax = 16U
};
/*********************** Driver Instance Definitions **************************/
static struct irq_ctrl_desc *intcDescPtr; // General interrupt controller descriptor
static struct timer_desc *logTmPtr;
static SYSBUS *sysbusDescPtr;
static PHY_INST *phyInstPtr;
static struct irq_ctrl_desc *intcDescPtr = NULL; // General interrupt controller descriptor
static struct timer_desc *logTmPtr = NULL;
static SYSBUS *sysbusDescPtr = NULL;
static PHY_INST *phyInstPtr = NULL;
static TMC_INST *tmcInstPtr = NULL;
L2_INST *linkInstPtr;
L2_INST *linkInstPtr = NULL;
static struct hmc7044_dev *hmc7044_inst;
static struct ad9361_reg_dev *ad9361_1_reg_inst;
static struct ad9361_reg_dev *ad9361_2_reg_inst;
// static struct ad9361_rf_phy *ad9361_phy;
// static struct ad9361_rf_phy *ad9361_2_phy;
/****************************************************************************/
/**
* This function is responsible for initializing the SCUGIC instance, looking
@@ -360,8 +356,13 @@ void ScuTimer_IntrHandler(void *context)
xdesc = (struct xil_timer_desc *)(logTmPtr->extra);
if (XScuTimer_IsExpired((XScuTimer *)xdesc->instance))
{
// Update log
Phy_UpdateHwSate(phyInstPtr);
// Refresh log
Phy_RefreshHwSate(phyInstPtr);
if (TimeCtrl_GetIntCnt(tmcInstPtr) - phyInstPtr->lastLogTime >= PHY_LOG_EXPIRE)
{
Phy_UpdateLogging(phyInstPtr);
}
XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
}
else
@@ -370,355 +371,6 @@ void ScuTimer_IntrHandler(void *context)
}
}
/*****************************************************************************/
/**
* @brief Hardware_SwitchFreq
*
* @param dev
* @param freq
*
* @return None.
*
******************************************************************************/
int Hardware_SwitchFreq(struct ad9361_reg_dev *dev, ad9361TxFreq freq)
{
int32_t status = 0;
uint8_t value = 0;
int32_t time_out_cnt = 0;
switch (freq)
{
case TX_FREQ_125:
{
//************************************************************
// Setup Tx Frequency-Dependent Syntheisizer Registers
//************************************************************
status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0]
status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0]
status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0]
status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0]
status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0]
status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0]
status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0]
status = ad9361_reg_write(dev, 0x027B, 0x94); // Set Synth Loop Filter charge pump current (Icp)
status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1
status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3
status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3
//************************************************************
// Write Tx Frequency Words
//************************************************************
status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0]
status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8]
status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16]
status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8]
status = ad9361_reg_write(dev, 0x0271, 0xA0); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal)
status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting
//************************************************************
// Tx Quadrature Calibration Settings
//************************************************************
status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency
status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6])
status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable
status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count
status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp
status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index
status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count
status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used
status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration
status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal
break;
}
case TX_FREQ_126:
{
//************************************************************
// Setup Tx Frequency-Dependent Syntheisizer Registers
//************************************************************
status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0]
status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0]
status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0]
status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0]
status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0]
status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0]
status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0]
status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp)
status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1
status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3
status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3
//************************************************************
// Write Tx Frequency Words
//************************************************************
status = ad9361_reg_write(dev, 0x0273, 0x06); // Write Tx Synth Fractional Freq Word[7:0]
status = ad9361_reg_write(dev, 0x0274, 0xD7); // Write Tx Synth Fractional Freq Word[15:8]
status = ad9361_reg_write(dev, 0x0275, 0x23); // Write Tx Synth Fractional Freq Word[22:16]
status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8]
status = ad9361_reg_write(dev, 0x0271, 0xA1); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal)
status = ad9361_reg_write(dev, 0x0005, 0x57); // Set LO divider setting
//************************************************************
// Tx Quadrature Calibration Settings
//************************************************************
status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency
status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6])
status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable
status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count
status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp
status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00AA, 0x22); // Set Tx Quad Cal Gain Table index
status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count
status = ad9361_reg_write(dev, 0x00AE, 0x00); // Set Tx Quad Cal LPF Gain index incase Split table mode used
status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration
status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal
break;
}
case TX_FREQ_4125:
{
//************************************************************
// Setup Tx Frequency-Dependent Syntheisizer Registers
//************************************************************
status = ad9361_reg_write(dev, 0x027A, 0x4A); // Set VCO Output level[3:0]
status = ad9361_reg_write(dev, 0x0279, 0xC1); // Set Init ALC Value[3:0] and VCO Varactor[3:0]
status = ad9361_reg_write(dev, 0x0282, 0x0E); // Set VCO Bias Tcf[1:0] and VCO Bias Ref[2:0]
status = ad9361_reg_write(dev, 0x0278, 0x78); // Set VCO Cal Offset[3:0]
status = ad9361_reg_write(dev, 0x0285, 0x00); // Set VCO Cal Ref Tcf[2:0]
status = ad9361_reg_write(dev, 0x0291, 0x0B); // Set VCO Varactor Reference[3:0]
status = ad9361_reg_write(dev, 0x0290, 0x70); // Set VCO Varactor Ref Tcf[2:0] and VCO Varactor Offset[3:0]
status = ad9361_reg_write(dev, 0x027B, 0x93); // Set Synth Loop Filter charge pump current (Icp)
status = ad9361_reg_write(dev, 0x027E, 0xF4); // Set Synth Loop Filter C2 and C1
status = ad9361_reg_write(dev, 0x027F, 0xDF); // Set Synth Loop Filter R1 and C3
status = ad9361_reg_write(dev, 0x0280, 0x0A); // Set Synth Loop Filter R3
//************************************************************
// Write Rx Frequency Words
//************************************************************
status = ad9361_reg_write(dev, 0x0273, 0x00); // Write Tx Synth Fractional Freq Word[7:0]
status = ad9361_reg_write(dev, 0x0274, 0x00); // Write Tx Synth Fractional Freq Word[15:8]
status = ad9361_reg_write(dev, 0x0275, 0x00); // Write Tx Synth Fractional Freq Word[22:16]
status = ad9361_reg_write(dev, 0x0272, 0x00); // Write Tx Synth Integer Freq Word[10:8]
status = ad9361_reg_write(dev, 0x0271, 0xA5); // Write Tx Synth Integer Freq Word[7:0] (starts VCO cal)
status = ad9361_reg_write(dev, 0x0005, 0x07); // Set LO divider setting
//************************************************************
// Tx Quadrature Calibration Settings
//************************************************************
status = ad9361_reg_write(dev, 0x00A0, 0x75); // Set TxQuadcal NCO frequency
status = ad9361_reg_write(dev, 0x00A3, 0xC0); // Set TxQuadcal NCO frequency (Only update bits [7:6])
status = ad9361_reg_write(dev, 0x00A1, 0x7B); // Tx Quad Cal Configuration, Phase and Gain Cal Enable
status = ad9361_reg_write(dev, 0x00A9, 0xFF); // Set Tx Quad Cal Count
status = ad9361_reg_write(dev, 0x00A2, 0x7F); // Set Tx Quad Cal Kexp
status = ad9361_reg_write(dev, 0x00A5, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00A6, 0x01); // Set Tx Quad Cal Magnitude Threshhold
status = ad9361_reg_write(dev, 0x00AA, 0x28); // Set Tx Quad Cal Gain Table index
status = ad9361_reg_write(dev, 0x00A4, 0xF0); // Set Tx Quad Cal Settle Count
status = ad9361_reg_write(dev, 0x00AE, 0x04); // Set Tx Quad Cal LPF Gain index incase Split table mode used
status = ad9361_reg_write(dev, 0x0169, 0xC0); // Disable Rx Quadrature Calibration before Running Tx Quadrature Calibration
status = ad9361_reg_write(dev, 0x0016, 0x10); // Start Tx Quad cal
break;
}
// Wait for cal to complete (Done when 0x016[4]==0)
time_out_cnt = 0;
do
{
status |= ad9361_reg_read(dev, 0x0016, &value);
mdelay(1); // Wait 1ms
time_out_cnt++;
} while ((value & 0x10) != 0x00 && time_out_cnt <= AD9361_TIMEOUT_TH);
}
return status;
}
/*****************************************************************************/
/**
* @brief Hardware_Init
*
* @param none.
*
* @return None.
*
******************************************************************************/
int Hardware_Init(void)
{
int32_t Status;
XGpioPs Gpio;
XGpioPs_Config *ConfigPtr;
ConfigPtr = XGpioPs_LookupConfig(AD9361_GPIO_DEVICE_ID);
Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr, ConfigPtr->BaseAddr);
if (Status != SUCCESS)
{
return FAILURE;
}
/**********************************************************/
/****************** HMC7044 Configuration *****************/
/**********************************************************/
Status = hmc7044_init(&hmc7044_inst, &hmc7044_default_init_param);
if (Status != SUCCESS)
{
DBG_ERROR("hmc7044_init() error: %" PRId32 "\n", Status);
return FAILURE;
}
/**********************************************************/
/***************** 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_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_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);
/**********************************************************/
/******* AD9361 Baseband Multichip Synchronization ********/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_SYNC, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_RX_FIFO_RST, AD9361_GPIO_OUTPUT);
// SYNC BBPLL and DIGITAL SAMPLING CLOCKS
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0D); // MCS RF Enable; MCS BBPLL Enable; MCS BB Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0D);
ad9361_reg_write(ad9361_1_reg_inst, 0x0047, 0x80); // MCS refclk Scale Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0047, 0x80);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0);
mdelay(20);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input a rising-edge pulse to the SYNC_IN pin
mdelay(500);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0);
mdelay(2000);
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0B); // MCS RF Enable; MCS Digital CLK Enable ; MCS BB Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0B);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 1); // Input another rising-edge pulse to the SYNC_IN pin
mdelay(500);
XGpioPs_WritePin(&Gpio, AD9361_SYNC, 0);
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x08); // clear MCS bits
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x08);
XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0);
mdelay(20);
XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 1);
mdelay(20);
XGpioPs_WritePin(&Gpio, AD9361_RX_FIFO_RST, 0);
/**********************************************************/
/********* AD9361 Multichip Rx Phase Calibration **********/
/**********************************************************/
XGpioPs_SetDirectionPin(&Gpio, AD9361_TX_SWITCH, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_START, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_1_CAL_DONE, AD9361_GPIO_INPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_START, AD9361_GPIO_OUTPUT);
XGpioPs_SetDirectionPin(&Gpio, AD9361_2_CAL_DONE, AD9361_GPIO_INPUT);
// switch to lower frequency
Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_126);
XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 1);
mdelay(20);
// switch rx channel
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x30);
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x30);
// enable dual ad9361 tx channels
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xE4); // Setup Tx Digital Filters/ Channels
// switch ad9361 tx channel
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x70); // Select Rx input pin(A,B,C)/ Tx out pin (A,B)
mdelay(20);
// begin to calibrate the 1st ad9361
XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0);
XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 1);
mdelay(1);
XGpioPs_WritePin(&Gpio, AD9361_1_CAL_START, 0);
// read calibration status
int32_t time_out_cnt = 0;
do
{
mdelay(1); // Wait 1ms
time_out_cnt++;
} while (((XGpioPs_ReadPin(&Gpio, AD9361_1_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH));
if (time_out_cnt == AD9361_TIMEOUT_TH)
{
return FAILURE;
}
// begin to calibrate the 2nd ad9361
XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 1);
mdelay(1);
XGpioPs_WritePin(&Gpio, AD9361_2_CAL_START, 0);
// read calibration status
time_out_cnt = 0;
do
{
mdelay(1); // Wait 1ms
time_out_cnt++;
} while (((XGpioPs_ReadPin(&Gpio, AD9361_2_CAL_DONE) == 0) && time_out_cnt <= AD9361_TIMEOUT_TH));
if (time_out_cnt == AD9361_TIMEOUT_TH)
{
return FAILURE;
}
// enable single ad9361 tx channels
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0002, 0xA4); // Setup Tx Digital Filters/ Channels
// switch ad9361 tx & rx channel
Status = ad9361_reg_write(ad9361_1_reg_inst, 0x0004, 0x03);
Status = ad9361_reg_write(ad9361_2_reg_inst, 0x0004, 0x03);
// switch to higher frequency
Status = Hardware_SwitchFreq(ad9361_1_reg_inst, TX_FREQ_4125);
XGpioPs_WritePin(&Gpio, AD9361_TX_SWITCH, 0);
DBG_PRINT("Done.\n");
return 0;
}
/*****************************************************************************/
/**
* @brief Main function, initialize all the device needed, initialize
@@ -771,7 +423,7 @@ int main(void)
}
/* Physical Layer Initialize */
Status = Phy_InstInit(&phyInstPtr, &phyConfig);
Status = Phy_Init(&phyInstPtr, &phyConfig);
if (Status == SUCCESS)
{
DBG_PRINT("Physical layer Init SUCCESS! \n");
@@ -835,7 +487,7 @@ int main(void)
while (true)
{
// System bus handler
if (SystemBus_IsReqPendding(sysbusDescPtr))
if (SystemBus_IsReqPending(sysbusDescPtr))
{
Status = SystemBus_HandleCmd(sysbusDescPtr);
if (Status != SUCCESS)
@@ -843,7 +495,7 @@ int main(void)
DBG_ERROR("SystemBus_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
}
}
if (SystemBus_IsRsqPendding(sysbusDescPtr) && (!SystemBus_IsTxBusy(sysbusDescPtr)))
if (SystemBus_IsRsqPending(sysbusDescPtr) && (!SystemBus_IsTxBusy(sysbusDescPtr)))
{
// FIXME: Required by 12 (CASC)
udelay(4000);
@@ -1,19 +1,25 @@
/*****************************************************************************/
/**
* Description: Functions for framing operations.
* @file framing.h
* @author FanHao ([email protected])
* @brief DF Linklayer framing functions.
* @version 0.0
* @date 2023-05-06
*
* Date: 2022-07-16 14:17
* LastEditors: Fan Hao
* LastEditTime: 2022-07-16 17:11
* Revisions: Rev 0.0
* History:
* [2022-07-16]: Description of modification.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Framing
* @{
*/
/***************************** Include Files *********************************/
#include <stdint.h>
#include <string.h>
@@ -159,7 +165,7 @@ bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType)
ASSERT(dataBuff != NULL);
int32_t Status;
uint32_t crcVal;
crcVal = 0;
crcVal = 0U;
Status = L2_CrcGen(dataBuff, dataLen, crcType, &crcVal);
if (Status == SUCCESS)
{
@@ -177,3 +183,7 @@ bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType)
return false;
}
}
/** @} LinkLayer_Framing*/
/** @} LinkLayer*/
@@ -1,8 +1,28 @@
//
// Copyright (C) 2020 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
/*****************************************************************************/
/**
* @file coord.c
* @author FanHao ([email protected])
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @addtogroup LinkLayerGeometry_Coord
* @{
*/
#include <math.h>
#include "coord.h"
@@ -55,6 +75,10 @@ COORD Coord_GetScalarMult(COORD a, double t)
/** @brief Divides a coordinate vector by a real number. */
void Coord_ScalarDiv(COORD *a, double t)
{
if (t == 0.0) {
*a = COORD_NIL;
return;
}
a->x /= t;
a->y /= t;
a->z /= t;
@@ -63,6 +87,9 @@ void Coord_ScalarDiv(COORD *a, double t)
/** @brief Divides a coordinate vector by a real number. */
COORD Coord_GetScalarDiv(COORD a, double t)
{
if (t == 0.0) {
return COORD_NIL;
}
COORD ret;
ret.x = a.x / t;
ret.y = a.y / t;
@@ -209,3 +236,9 @@ COORD Coord_Launch2Inertia(COORD o, COORD p, double A, double B, double we, doub
return ret;
}
/** @} LinkLayerGeometry_Coord */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,20 +1,36 @@
//
// Copyright (C) 2020 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
/*****************************************************************************/
/**
* @file coord.h
* @author FanHao ([email protected])
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
#ifndef _COORD_H
#define _COORD_H
/**
* @brief Structure for storing 3D coordinates.
*
* Some comparison and basic arithmetic operators are implemented.
*
* @ingroup utils
* @addtogroup LinkLayer
* @{
*/
/**
* @defgroup LinkLayerGeometry
* @{
*/
/**
* @defgroup LinkLayerGeometry_Coord
* @{
*/
/**
* @struct COORD
* @brief Structure for storing 3D coordinates.
*/
typedef struct
{
double x;
@@ -78,3 +94,9 @@ COORD Coord_GetNormalized(COORD a);
double Coord_Angle(COORD a, COORD b);
#endif
/** @} LinkLayerGeometry_Coord */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,8 +1,29 @@
//
// Copyright (C) 2020 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
/*****************************************************************************/
/**
* @file eulerangles.c
* @author FanHao ([email protected])
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @addtogroup LinkLayerGeometry_EulerAngles
* @{
*/
#include <math.h>
#include "eulerangles.h"
@@ -48,9 +69,9 @@ EULERANGLES EulerAngles_GetScalarMult(EULERANGLES e, double f)
/** @brief Normalize EulerAngles. */
void EulerAngles_Normalize(EULERANGLES *e)
{
e->alpha = fmod(e->alpha, 2 * EUL_PI);
e->beta = fmod(e->beta, 2 * EUL_PI);
e->gamma = fmod(e->gamma, 2 * EUL_PI);
e->alpha = fmod(e->alpha, 2.0 * EUL_PI);
e->beta = fmod(e->beta, 2.0 * EUL_PI);
e->gamma = fmod(e->gamma, 2.0 * EUL_PI);
}
/** @brief Normalize EulerAngles. */
@@ -59,3 +80,9 @@ EULERANGLES EulerAngles_GetNormalize(EULERANGLES e)
EulerAngles_Normalize(&e);
return e;
}
/** @} LinkLayerGeometry_EulerAngles */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,10 +1,37 @@
/*****************************************************************************/
/**
* @file eulerangles.h
* @author FanHao ([email protected])
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @defgroup LinkLayerGeometry_EulerAngles
* @{
*/
#ifndef __EULERANGLES_H
#define __EULERANGLES_H
#define EUL_PI 3.14159265358979323846
#define DEG2RAD(d) ((EUL_PI / 180.0) * d)
#define RAD2DEG(r) ((180.0 / EUL_PI) * r)
#define DEG2RAD(d) ((EUL_PI / 180.0) * (d))
#define RAD2DEG(r) ((180.0 / EUL_PI) * (r))
/**
* Orientations are represented by 3D double precision Tait-Bryan (Euler) tuples
@@ -16,6 +43,11 @@
* rotation along the Y axis rotates Z into X (leans forward), positive rotation
* along the X axis rotates Y into Z (leans right).
*/
/**
* @struct EULERANGLES
* @brief Structure for standard quaternion
*/
typedef struct
{
double alpha; // unit rad
@@ -53,3 +85,9 @@ void EulerAngles_Normalize(EULERANGLES *e);
EULERANGLES EulerAngles_GetNormalize(EULERANGLES e);
#endif
/** @} LinkLayerGeometry_EulerAngles */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,8 +1,29 @@
//
// Copyright (C) 2014 OpenSim Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
//
/*****************************************************************************/
/**
* @file quaternion.c
* @author FanHao ([email protected])
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @addtogroup LinkLayerGeometry_Quaternion
* @{
*/
#include <math.h>
#include <stdint.h>
@@ -28,6 +49,7 @@ const SOFT_DOUBLE EPS_DOUBLE = {.raw = 0x3CB0000000000000};
const QUATERNION QUATERNION_IDENTITY = {1.0, 0.0, 0.0, 0.0};
const QUATERNION QUATERNION_NIL = {NAN, NAN, NAN, NAN};
/** @brief Subtracts two quaternions. */
QUATERNION Quaternion_Sub(QUATERNION q1, QUATERNION q2)
{
@@ -69,6 +91,10 @@ QUATERNION Quaternion_GetScalarMult(QUATERNION a, double t)
/** @brief Divides a quaternion by a real number. */
void Quaternion_ScalarDiv(QUATERNION *q, double t)
{
if (t == 0.0) {
*q = QUATERNION_NIL;
return;
}
q->s /= t;
q->i /= t;
q->j /= t;
@@ -168,6 +194,9 @@ inline double Quaternion_GetRotationAngle(QUATERNION q)
/** @brief Get axis of quaternion. */
COORD Quaternion_GetRotationAxis(QUATERNION q)
{
if ((q.s > 1.0) || (q.s < -1.0)) {
return COORD_NIL;
}
double sin_theta_inv;
COORD ret;
sin_theta_inv = 1.0 / sin(acos(q.s));
@@ -180,6 +209,12 @@ COORD Quaternion_GetRotationAxis(QUATERNION q)
/** @brief Get the axis and rotate angle of a unit Quaternion */
void Quaternion_GetRotationAxisAndAngle(QUATERNION q, COORD *axis, double *angle)
{
if ((q.s > 1.0) || (q.s < -1.0)) {
*axis = COORD_NIL;
*angle = NAN;
return;
}
double sin_theta_inv;
*angle = acos(q.s);
@@ -196,6 +231,11 @@ void Quaternion_GetRotationAxisAndAngle(QUATERNION q, COORD *axis, double *angle
/** @brief Decompose the rotation on to 2 parts. */
void Quaternion_GetSwingAndTwist(QUATERNION q, COORD axis, QUATERNION *swing, QUATERNION *twist)
{
if ((swing == NULL) || (twist == NULL))
{
return;
}
double p;
COORD v;
v.x = q.i;
@@ -304,7 +344,7 @@ EULERANGLES Quaternion_ToEulerAngles(QUATERNION q, EULERANGLES_TYPE type)
if (mask1 || mask2)
{
ret.alpha = 0;
ret.gamma = (asinValue > 0) ? (2.0 * atan2(q.i, q.s)) : (-2.0 * atan2(q.i, q.s));
ret.gamma = (asinValue > 0.0) ? (2.0 * atan2(q.i, q.s)) : (-2.0 * atan2(q.i, q.s));
}
else
{
@@ -317,6 +357,7 @@ EULERANGLES Quaternion_ToEulerAngles(QUATERNION q, EULERANGLES_TYPE type)
default:
ret = EULERANGLES_NIL;
break;
}
return ret;
}
@@ -406,7 +447,7 @@ QUATERNION Quaternion_RotationFromTo(COORD from, COORD to)
QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t)
{
QUATERNION ret;
Quaternion_ScalarMult(&q1, 1 - t);
Quaternion_ScalarMult(&q1, 1.0 - t);
Quaternion_ScalarMult(&q1, t);
ret = Quaternion_Add(q1, q2);
Quaternion_Normalize(&ret);
@@ -450,3 +491,9 @@ QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t)
return Quaternion_Lerp(q1, q3, t);
}
}
/** @} LinkLayerGeometry_Quaternion */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,3 +1,29 @@
/*****************************************************************************/
/**
* @file quaternion.h
* @author FanHao ([email protected])
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayerGeometry
* @{
*/
/**
* @defgroup LinkLayerGeometry_Quaternion
* @{
*/
#ifndef __QUATERNION_H
#define __QUATERNION_H
@@ -5,7 +31,10 @@
#include "coord.h"
#include "eulerangles.h"
// borrowed and adapted from https://github.com/MegaManSE/willperone/blob/master/Math/quaternion.h
/**
* @struct QUATERNION
* @brief Structure for standard quaternion
*/
typedef struct
{
double s;
@@ -27,13 +56,13 @@ QUATERNION Quaternion_Add(QUATERNION q1, QUATERNION q2);
void Quaternion_ScalarMult(QUATERNION *q, double t);
/** @brief Multiplies a quaternion by a real number. */
QUATERNION Quaternion_GetScalarMult(QUATERNION a, double t);
QUATERNION Quaternion_GetScalarMult(QUATERNION q, double t);
/** @brief Divides a quaternion by a real number. */
void Quaternion_ScalarDiv(QUATERNION *q, double t);
/** @brief Divides a quaternion by a real number. */
QUATERNION Quaternion_GetScalarDiv(QUATERNION a, double t);
QUATERNION Quaternion_GetScalarDiv(QUATERNION q, double t);
/** @brief Multiplies two quaternions. */
QUATERNION Quaternion_Mult(QUATERNION q1, QUATERNION q2);
@@ -107,3 +136,9 @@ QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t);
QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t);
#endif
/** @} LinkLayerGeometry_Quaternion */
/** @} LinkLayerGeometry */
/** @} LinkLayer */
@@ -1,19 +1,21 @@
/*****************************************************************************/
/**
* Description: A brief description of this file
* @file link_layer.c
* @author FanHao ([email protected])
* @brief DF Linklayer implementation file.
* @version 0.1
* @date 2023-05-06
*
* Date: 2021-11-13 13:32
* LastEditTime: 2021-11-23 10:57
* Revisions: Rev 0.0
* History:
* [2021-11-23]: Initial version.
* [2022-03-28]: Add bre test mode.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/***************************** Include Files *********************************/
#include <stdlib.h>
#include <string.h>
@@ -31,17 +33,30 @@
#endif
/************************** Constant Definitions *****************************/
#define NET_START_TIME_INFTY UINT32_MAX
#define LINK_BROCK_THRESHOLD (3 * 200) // 3 secods
#define LINK_BROCK_THRESHOLD L2_SLOTS_PER_FRAME // 0.5 secods
/************************** Variable Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Function Prototypes ******************************/
static void L2_RcdShift(L2_RCD *rcd, int32_t netxVal);
static void L2_RcdShift(L2_RCD *rcd, uint32_t netxVal);
static void UpdateMainSate(L2_INST *instPtr, L2_NODE_STATE newSate);
static void L2_SetSlotNum(L2_INST *instPtr, uint32_t newSlotNum);
static void L2_SetFrameNum(L2_INST *instPtr, uint32_t newFrameNum);
static void L2_UpdateSlotNum(L2_INST *instPtr);
static void L2_DataAvailUpdate(L2_INST *instPtr, bool status);
static void L2_FrameStateUpdate(L2_INST *instPtr);
/**
* @brief Shift L2 status record.(newval->next->curr->last)
*/
inline void L2_RcdShift(L2_RCD *rcd, uint32_t netxVal)
{
ASSERT(rcd != NULL);
rcd->last = rcd->curr;
rcd->curr = rcd->next;
rcd->next = netxVal;
}
/**
* @brief helper function to update linkelayer state
@@ -101,6 +116,80 @@ static inline void L2_DataAvailUpdate(L2_INST *instPtr, bool status)
instPtr->dataAvail = status;
}
/*****************************************************************************/
/**
* @brief Update L2 frame state, check if there is any valid L2 frame data in
* data buffer, update receive frame status.
*
* @param instPtr a pointer to linklayer instance
*
* @return NONE.
*
******************************************************************************/
static void L2_FrameStateUpdate(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
bool isValid;
L2_FRAME_TYPE recvType = L2_GetLastOptFrameType(instPtr);
isValid = false;
// Update frame state.
if (Phy_IsFrameValid(phyRef) == false)
{
L2_DataAvailUpdate(instPtr, false);
}
else
{
DBG_INFO("A frame received, checking data validation...\n");
DBG_INFO("Last frame type is: %" PRId32 ".\n", instPtr->frame.last);
Phy_RetrieveRecvData(phyRef, instPtr->recvPktData);
instPtr->log.frameRecv++;
// Update frame state.
switch (recvType)
{
case L2_SCAN_FRAME:
case L2_ADV_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_ADV_PACK_LEN, L2_CRC16_1021);
instPtr->log.advRecvCnt++;
instPtr->log.advCorrectCnt = isValid ? instPtr->log.advCorrectCnt + 1 : instPtr->log.advCorrectCnt;
break;
case L2_CFM_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_CMF_PACK_LEN, L2_CRC16_1021);
instPtr->log.cfmRecvCnt++;
instPtr->log.cfmCorrectCnt = isValid ? instPtr->log.cfmCorrectCnt + 1 : instPtr->log.cfmCorrectCnt;
break;
case L2_SVC_FRAME:
#ifndef DATALINK_ENABLE_BERTEST
isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_LEN, L2_CRC16_1021);
#else
isValid = true;
#endif
instPtr->log.svcRecvCnt++;
instPtr->log.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt;
break;
default:
isValid = false;
break;
}
if (isValid)
{
instPtr->log.frameCorrect++;
L2_DataAvailUpdate(instPtr, true);
}
else
{
L2_DataAvailUpdate(instPtr, false);
}
}
}
/**
* @addtogroup LinkLayer_Utility
* @{
*/
/**
* @brief Get the current node ID.
*/
@@ -146,6 +235,15 @@ inline L2_NODE_STATE L2_GetMainState(L2_INST *instPtr)
return instPtr->mainState;
}
/**
* @brief Check if there is a valid l2 frame.
*/
inline bool L2_isStarted(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
return instPtr->isEnable;
}
/**
* @brief Check if there is a valid l2 frame.
*/
@@ -164,6 +262,14 @@ inline bool L2_isCxn2Net(L2_INST *instPtr)
return instPtr->cxn2Net;
}
/**
* @brief Get corresponding frame length in byte of L2 frame.
*/
inline uint32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType)
{
return Phy_GetFrameLen(L2_L2frame2L1frame(l2FrameType));
}
/**
* @brief Get last frame number.
*/
@@ -271,24 +377,6 @@ inline L2_TOR_TYPE L2_GetNextTor(L2_INST *instPtr)
return instPtr->tor.next;
}
/*****************************************************************************/
/**
* @brief Shift L2 status record.(newval->next->curr->last)
*
* @param instPtr A pointer to physical layer control instance.
*
* @return NONE.
*
******************************************************************************/
inline void L2_RcdShift(L2_RCD *rcd, int32_t netxVal)
{
ASSERT(rcd != NULL);
rcd->last = rcd->curr;
rcd->curr = rcd->next;
rcd->next = netxVal;
}
// FIXME:
/*****************************************************************************/
/**
* @brief Infer last received frame type.
@@ -316,342 +404,6 @@ L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr)
return L2_NONE_FRAME;
}
}
/*****************************************************************************/
/**
* @brief Update L2 frame state, check if there is any valid L2 frame data in
* data buffer, update receive frame status.
*
* @param instPtr a pointer to linklayer instance
*
* @return NONE.
*
******************************************************************************/
void L2_FrameStateUpdate(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
bool isValid;
L2_FRAME_TYPE recvType = L2_GetLastOptFrameType(instPtr);
L2_FRAME_TYPE sendType = L2_GetNextFrameType(instPtr);
// Update frame state.
if (Phy_IsFrameValid(phyRef) == false)
{
L2_DataAvailUpdate(instPtr, false);
}
else
{
DBG_INFO("A frame received, checking data validation...\n");
DBG_INFO("Last frame type is: %" PRId32 ".\n", instPtr->frame.last);
Phy_RetrieveRecvData(phyRef, instPtr->recvPktData);
instPtr->log.frameRecv++;
// Update frame state.
// FIXME: add log
switch (recvType)
{
case L2_SCAN_FRAME:
case L2_ADV_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_ADV_PACK_LEN, L2_CRC16_1021);
instPtr->log.advRecvCnt++;
instPtr->log.advCorrectCnt = isValid ? instPtr->log.advCorrectCnt + 1 : instPtr->log.advCorrectCnt;
break;
case L2_CFM_FRAME:
isValid = L2_CrcCheck(instPtr->recvPktData, L2_CMF_PACK_LEN, L2_CRC16_1021);
instPtr->log.cfmRecvCnt++;
instPtr->log.cfmCorrectCnt = isValid ? instPtr->log.cfmCorrectCnt + 1 : instPtr->log.cfmCorrectCnt;
break;
case L2_SVC_FRAME:
#ifndef DATALINK_ENABLE_BERTEST
isValid = L2_CrcCheck(instPtr->recvPktData, L2_SVC_PACK_LEN, L2_CRC16_1021);
#else
isValid = true;
#endif
instPtr->log.svcRecvCnt++;
instPtr->log.svcCorrectCnt = isValid ? instPtr->log.svcCorrectCnt + 1 : instPtr->log.svcCorrectCnt;
break;
default:
isValid = false;
break;
}
if(isValid)
{
instPtr->log.frameCorrect++;
L2_DataAvailUpdate(instPtr, true);
}
else
{
L2_DataAvailUpdate(instPtr, false);
}
}
// Logging status.
// -- send slot status
if (instPtr->tor.curr == L2_TOR_RX)
{
instPtr->rxSlotLog.tuNo = L2_GetCurrentFrameNum(instPtr);
instPtr->rxSlotLog.slotNo = L2_GetCurrentSlotNum(instPtr);
instPtr->rxSlotLog.frameType = recvType;
memset(instPtr->rxSlotLog.payload, 0x00, sizeof(instPtr->rxSlotLog.payload));
if (isValid == true)
{
memcpy(instPtr->rxSlotLog.payload,
instPtr->recvPktData,
Phy_GetFrameLen(L2_L2frame2L1frame(recvType)));
TIME_WORD timeWrod;
Phy_GetLastReceivedFrameSyncTimeStamp(phyRef, &timeWrod);
instPtr->rxSlotLog.tmStamp = timeWrod.frac_part;
instPtr->rxSlotLog.tmStamp += (uint64_t)timeWrod.int_part * TIME_FRAC_MAX;
// Log time deviation.
instPtr->txSlotLog.tmDevi = 0; // TODO:
// Log frequency deviation
instPtr->rxSlotLog.freqDevi = (uint32_t)Phy_GetFreqEst(phyRef);
}
else
{
instPtr->rxSlotLog.tmStamp = 0;
instPtr->rxSlotLog.tmDevi = 0;
instPtr->rxSlotLog.freqDevi = 0;
memset(instPtr->rxSlotLog.payload, 0x00, sizeof(instPtr->rxSlotLog.payload));
}
SysMonitor_UpdateRecvSlotLog(&(instPtr->rxSlotLog));
}
// -- send slot status
if (instPtr->tor.next == L2_TOR_TX)
{
instPtr->txSlotLog.tuNo = L2_GetCurrentFrameNum(instPtr);
instPtr->txSlotLog.slotNo = L2_GetCurrentSlotNum(instPtr);
instPtr->txSlotLog.frameType = sendType;
memset(instPtr->rxSlotLog.payload, 0x00, sizeof(instPtr->txSlotLog.payload));
memcpy(instPtr->txSlotLog.payload,
instPtr->sendPktData,
Phy_GetFrameLen(L2_L2frame2L1frame(sendType)));
instPtr->txSlotLog.tmStamp = 0;
instPtr->txSlotLog.tmDevi = 0;
instPtr->txSlotLog.freqDevi = 0;
SysMonitor_UpdateSendSlotLog(&(instPtr->txSlotLog));
}
}
/*****************************************************************************/
/**
* @brief Steer antenna beam to specified node.
*
* @param instPtr a pointer to link layer descriptor instance
* @param nodeId destination node
*
* @return Corresponding frame length
* L2_FRAME_NONE_LEN if the frame type code cannot be recognized.
*
******************************************************************************/
// FIXME: To Complete.
int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId)
{
ASSERT(instPtr != NULL);
ASSERT(instPtr->config.phyInstPtr != NULL);
int32_t Status;
COORD myPos, dstPos, beamDir;
Status = L2_GetNodePos(instPtr->nodeList, nodeId, &dstPos);
if (Status != SUCCESS)
{
DBG_ERROR("Failed to retrieve position info of node %" PRIu8 ", remain last configuration.\n", nodeId);
return EPARAM;
}
myPos.x = instPtr->sysInfo.posX;
myPos.y = instPtr->sysInfo.posY;
myPos.z = instPtr->sysInfo.posZ;
// TODO Check data format
EULERANGLES attitudeEuler, antAttitudeEuler;
attitudeEuler.alpha = DEG2RAD(instPtr->sysInfo.pitch);
attitudeEuler.beta = DEG2RAD(instPtr->sysInfo.yaw);
attitudeEuler.gamma = DEG2RAD(instPtr->sysInfo.roll);
// FIXME: confirm date source.
antAttitudeEuler.alpha = DEG2RAD(0);
antAttitudeEuler.beta = DEG2RAD(0);
antAttitudeEuler.gamma = DEG2RAD(0);
// TODO Check data format
QUATERNION attitude, antAttitude;
attitude = Quaternion_FromeEulerAngles(attitudeEuler, EULERANGLES_XYZ);
antAttitude = Quaternion_FromeEulerAngles(antAttitudeEuler, EULERANGLES_XYZ);
// --- --- Algorithm --- ---
// TODO Check result validation
// Compute beam direction vector
beamDir = Coord_Sub(dstPos, myPos);
// Compute antenna attitude respect to ECEF
antAttitude = Quaternion_Mult(attitude, antAttitude);
// Convert beam direction vector to antenna coordinate
beamDir = Quaternion_Rotate(Quaternion_GeInverse(antAttitude), beamDir);
// Normalize
Coord_Normalize(&beamDir);
double oAxis, rAxis;
oAxis = RAD2DEG(atan2(beamDir.z, beamDir.y));
rAxis = RAD2DEG(acos(Coord_Dot(beamDir, COORD_X_AXIS)));
Status = Phy_SetBeamAngle(instPtr->config.phyInstPtr, oAxis, rAxis);
return Status;
}
/*****************************************************************************/
/**
* @brief Layer 2 setup next slot operation, update current operating frame.
*
* @param instPtr a pointer to linklayer instance
* @param txrxMode tx/rx state for next slot
* @param frameType frame type of next slot.
*
* @return Corresponding frame length
* L2_FRAME_NONE_LEN if the frame type code cannot be recognized.
*
******************************************************************************/
int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType)
{
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
int32_t Status;
if (frameType < L2_SCAN_FRAME || frameType > L2_SVC_FRAME)
{
return FAILURE;
}
// logging
if (txrxMode == L2_TOR_TX)
{
instPtr->log.frameTx++;
switch (frameType)
{
case L2_ADV_FRAME:
instPtr->log.advTxCnt++;
break;
case L2_CFM_FRAME:
instPtr->log.cfmTxCnt++;
break;
case L2_SVC_FRAME:
instPtr->log.svcTxCnt++;
break;
default:
break;
}
}
else if (txrxMode == L2_TOR_RX)
{
instPtr->log.frameRx++;
switch (frameType)
{
case L2_ADV_FRAME:
instPtr->log.advRxCnt++;
break;
case L2_CFM_FRAME:
instPtr->log.cfmRxCnt++;
break;
case L2_SVC_FRAME:
instPtr->log.svcRxCnt++;
break;
default:
break;
}
}
#if _DEBUG_LEVEL >= 3
char *torStr = NULL;
char *frameStr = NULL;
switch (txrxMode)
{
case L2_TOR_SUSPEND:
torStr = "SUSPEND";
break;
case L2_TOR_TX:
torStr = "TX";
break;
case L2_TOR_RX:
torStr = "RX";
break;
}
switch (frameType)
{
case L2_SCAN_FRAME:
frameStr = "Scan";
break;
case L2_ADV_FRAME:
frameStr = "Advertisement";
break;
case L2_CFM_FRAME:
frameStr = "Confirm";
break;
case L2_SVC_FRAME:
frameStr = "Service";
break;
default:
frameStr = "UNKNOWN Frame";
break;
}
DBG_INFO("# Setup Next Slot # [%" PRIu32 "-%" PRIu32 "], %s, %s.\n",
instPtr->frameNum.next,
instPtr->slotNum.next,
torStr, frameStr);
#endif
// Update frame and tx/rx mode record.
// Frame types shift (last <- curr <- next)
L2_RcdShift(&(instPtr->frame), frameType);
L2_RcdShift(&(instPtr->tor), txrxMode);
TIME_WORD pullTime = {0, 0};
pullTime.int_part = TimeCtrl_GetIntCnt(instPtr->config.tmcInstPtr) + 1;
Status = Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL);
if (Status != SUCCESS)
{
DBG_ERROR("Physical set pull time failed, with error code: %" PRId32 "\n", Status);
}
PHY_TOR_TYPE tor;
switch (txrxMode)
{
case L2_TOR_SUSPEND:
tor = PHY_TOR_SUSPEND;
break;
case L2_TOR_TX:
tor = PHY_TOR_TX;
break;
case L2_TOR_RX:
tor = PHY_TOR_RX;
break;
default:
DBG_ERROR("Invalid txrx mode :%" PRId8 ".\n", txrxMode);
return EPARAM;
}
Status = Phy_SetupNextSlot(phyRef, tor, L2_L2frame2L1frame(frameType), instPtr->sendPktData);
if (Status != SUCCESS)
{
DBG_ERROR("Physical setup failed, with error code: %" PRId32 "\n", Status);
}
return Status;
}
/*****************************************************************************/
/**
* @brief Get corresponding frame length in byte of L2 frame.
*
* @param l2FrameType
*
* @return Corresponding frame length
* L2_FRAME_NONE_LEN if the frame type code cannot be recognized.
*
******************************************************************************/
uint32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType)
{
return Phy_GetFrameLen(L2_L2frame2L1frame(l2FrameType));
}
/*****************************************************************************/
/**
* @brief Convert L2 frame type to L1 frame type
@@ -676,6 +428,12 @@ L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame)
return L1_NONE_FRAME;
}
}
/** @} LinkLayer_Utility*/
/**
* @defgroup LinkLayer_Main
* @{
*/
/*****************************************************************************/
/**
@@ -710,7 +468,15 @@ int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config)
DBG_ERROR("Allocate memory for L2_InstPtr failed.\n");
return ENOMEM;
}
// Clear random content
memset(*instPtr, 0x00, sizeof(L2_INST));
(*instPtr)->sendPktData = NULL;
(*instPtr)->recvPktData = NULL;
(*instPtr)->schdEventPool = NULL;
(*instPtr)->nodeList = NULL;
(*instPtr)->scanFSM = NULL;
(*instPtr)->serviceFSM = NULL;
memcpy(&((*instPtr)->config), config, sizeof(L2_CONFIG));
// Packet buffer
@@ -718,15 +484,15 @@ int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config)
if ((*instPtr)->sendPktData == NULL)
{
DBG_ERROR("Allocate memory for sendPktData failed.\n");
Status = ENOMEM;
goto init_error;
Linklayer_Destroy(*instPtr);
return ENOMEM;
}
(*instPtr)->recvPktData = calloc(L2_PACK_LEN_MAX / sizeof(uint64_t), sizeof(uint64_t));
if ((*instPtr)->recvPktData == NULL)
{
DBG_ERROR("Allocate memory for recvPktData failed.\n");
Status = ENOMEM;
goto init_error;
Linklayer_Destroy(*instPtr);
return ENOMEM;
}
// Reset basic info
(*instPtr)->netStartTime = NET_START_TIME_INFTY;
@@ -734,7 +500,7 @@ int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config)
(*instPtr)->rtneConfig.curr = NULL;
(*instPtr)->rtneConfig.next = NULL;
(*instPtr)->isEnable = false;
(*instPtr)->cxn2Net = (config->myType == L2_NODE_HEAD) ? true : false;;
(*instPtr)->cxn2Net = (config->myType == L2_NODE_HEAD) ? true : false;
(*instPtr)->dataAvail = false;
(*instPtr)->frameNum.last = 0;
(*instPtr)->frameNum.curr = 0;
@@ -769,32 +535,33 @@ int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config)
if (Status != SUCCESS)
{
DBG_ERROR("L2_CreateSchedEventPool runs failed, with error code: %" PRId32 ".\n", Status);
goto init_error;
Linklayer_Destroy(*instPtr);
return Status;
}
Status = L2_NodeList_Init(&((*instPtr)->nodeList));
if (Status != SUCCESS)
{
DBG_ERROR("NodeList_Init runs failed, with error code: %" PRId32 ".\n", Status);
goto init_error;
Linklayer_Destroy(*instPtr);
return Status;
}
Status = L2_Scan_Init(&((*instPtr)->scanFSM));
if (Status != SUCCESS)
{
goto init_error;
Linklayer_Destroy(*instPtr);
return Status;
}
Status = L2_Service_Init(&((*instPtr)->serviceFSM));
if (Status != SUCCESS)
{
goto init_error;
Linklayer_Destroy(*instPtr);
return Status;
}
return SUCCESS;
init_error:
Linklayer_Destroy(*instPtr);
return Status;
}
/*****************************************************************************/
@@ -830,7 +597,7 @@ int32_t Linklayer_Reconfig(L2_INST *instPtr, const L2_CONFIG *config)
instPtr->rtneConfig.last = NULL;
instPtr->rtneConfig.curr = NULL;
instPtr->rtneConfig.next = NULL;
instPtr->cxn2Net = false;
instPtr->cxn2Net = (config->myType == L2_NODE_HEAD) ? true : false;
instPtr->dataAvail = false;
instPtr->frameNum.last = 0;
instPtr->frameNum.curr = 0;
@@ -878,7 +645,10 @@ int32_t Linklayer_Reconfig(L2_INST *instPtr, const L2_CONFIG *config)
******************************************************************************/
void Linklayer_Destroy(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
if (instPtr == NULL)
{
return;
}
free(instPtr->sendPktData);
free(instPtr->recvPktData);
// Destroy FSMs and nodeList
@@ -902,7 +672,8 @@ int32_t Linklayer_Start(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
// Set netStartTime at first call.
if (instPtr->netStartTime == NET_START_TIME_INFTY) {
if (instPtr->netStartTime == NET_START_TIME_INFTY)
{
instPtr->netStartTime = TimeCtrl_GetIntCnt(instPtr->config.tmcInstPtr) / L2_SLOTS_PER_FRAME + 1;
}
instPtr->isEnable = true;
@@ -994,7 +765,7 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event)
case L2_EV_LOST_CXN:
{
DBG_INFO("Event L2_EV_LOST_CXN asserted....\n");
if (instPtr->config.myType == L2_NODE_HEAD)
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
DBG_ERROR("Illegal event, only None_Head node can assert L2_EV_LOST_CXN.\n");
break;
@@ -1004,6 +775,7 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event)
L2_Service_Reset(instPtr->serviceFSM);
instPtr->cxn2Net = false;
UpdateMainSate(instPtr, L2_INIT_STATE);
instPtr->log.reconnectCnt++;
break;
}
case L2_EV_LOST_NODE:
@@ -1012,6 +784,8 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event)
L2_Scan_Reset(instPtr->scanFSM);
L2_Service_Reset(instPtr->serviceFSM);
UpdateMainSate(instPtr, L2_INIT_STATE);
// Log reconnect
instPtr->log.reconnectCnt++;
break;
}
case L2_ROUTINE_FINISH:
@@ -1033,7 +807,8 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event)
}
else
{
DBG_WARNING("Unsupported routine state [%" PRId8 "], Continue withe previous routine table.\n", instPtr->nextState);
DBG_WARNING("Unsupported routine state [%" PRId8 "], "
"Continue with previous routine table.\n", instPtr->nextState);
}
break;
}
@@ -1182,6 +957,8 @@ static int32_t Linklayer_Routine(L2_INST *instPtr)
L2_IterEditNode(instPtr->nodeList, &increment, IntcNodeTTL);
#ifdef DATALINK_ENABLE_AUTORECONNECT
if (L2_GetMainState(instPtr) != L2_INIT_STATE)
{
L2_IterDeleteNode(instPtr->nodeList, IsNodeConnected);
if (L2_GetNodeListLen(instPtr->nodeList) < instPtr->config.netScale - 1)
{
@@ -1192,6 +969,7 @@ static int32_t Linklayer_Routine(L2_INST *instPtr)
l2Event.msg = NULL;
AssertL2Event(instPtr, &l2Event);
}
}
#endif
return Status;
}
@@ -1210,6 +988,8 @@ int32_t Linklayer_Proc(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
PHY_INST *phyRef = instPtr->config.phyInstPtr;
TMC_INST *tmcRef = instPtr->config.tmcInstPtr;
if (instPtr->isEnable == false)
{
@@ -1218,7 +998,7 @@ int32_t Linklayer_Proc(L2_INST *instPtr)
}
// FIXME: Consider time wrapping.
uint32_t nextTimeUnit = (TimeCtrl_GetIntCnt(instPtr->config.tmcInstPtr) + 1) / L2_SLOTS_PER_FRAME;
uint32_t nextTimeUnit = (TimeCtrl_GetIntCnt(tmcRef) + 1) / L2_SLOTS_PER_FRAME;
if (nextTimeUnit < instPtr->netStartTime)
{
DBG_WARNING("Linklayer not start yet, next time unit: %" PRIu32 ", start time unit: %" PRIu32 ".\n",
@@ -1250,19 +1030,19 @@ int32_t Linklayer_Proc(L2_INST *instPtr)
// Run Link layer routine, setup next slot procedure.
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
Phy_SetMode(instPtr->config.phyInstPtr, PHY_MODE_PULL);
Phy_SetMode(phyRef, PHY_MODE_PULL);
Status = Linklayer_Routine(instPtr);
}
else
{ // L2_NODE_MEMBER
if (L2_isCxn2Net(instPtr))
{
Phy_SetMode(instPtr->config.phyInstPtr, PHY_MODE_PULL);
Phy_SetMode(phyRef, PHY_MODE_PULL);
Status = Linklayer_Routine(instPtr);
}
else
{
Phy_SetMode(instPtr->config.phyInstPtr, PHY_MODE_LISTEN);
Phy_SetMode(phyRef, PHY_MODE_LISTEN);
Status = L2_Scan_Proc(instPtr);
}
}
@@ -1276,25 +1056,233 @@ int32_t Linklayer_Proc(L2_INST *instPtr)
// Check and execute scheduled event.
L2_EventPoolHandler(instPtr);
PHY_INST* phyRef = instPtr->config.phyInstPtr;
TMC_INST* tmcRef = instPtr->config.tmcInstPtr;
TIME_WORD timeWord;
// Update Protocol log
instPtr->prtcLog.tmSys = instPtr->frameNum.last * L2_SLOTS_PER_FRAME + instPtr->slotNum.last;
instPtr->prtcLog.phySt = 0; // TODO: Update physical state.
TimeCtrl_GetCurrentTime(tmcRef, &timeWord);
instPtr->prtcLog.tmLocal = timeWord.frac_part; // us
instPtr->prtcLog.tmLocal += (uint64_t)timeWord.int_part * TIME_FRAC_MAX; // us
instPtr->prtcLog.beamNo = phyRef->beamNo.last;
instPtr->prtcLog.beamNo = phyRef->beamWd.last;
instPtr->prtcLog.stage = instPtr->mainState;
instPtr->prtcLog.recvCnt = instPtr->log.frameRecv;
instPtr->prtcLog.recvCorrect = instPtr->log.frameCorrect;
SysMonitor_UpdateProtocolLog(&(instPtr->prtcLog));
// Update link layer state.
instPtr->mainState = instPtr->nextState;
instPtr->linkLog.tuNum = instPtr->frameNum.curr;
instPtr->linkLog.slotNum = (uint8_t)instPtr->slotNum.curr;
instPtr->linkLog.nodeType = (L2_GetNodeType(instPtr) == L2_NODE_HEAD) ? 0xAA : 0xCC;
instPtr->linkLog.cxnStatus = (L2_isCxn2Net(instPtr)) ? 0x11 : 0x00;
instPtr->linkLog.linkStage = (instPtr->mainState == L2_INIT_STATE) ? 0x11 : 0x22;
instPtr->linkLog.recxnCnt = instPtr->log.reconnectCnt;
instPtr->linkLog.beamNo = instPtr->scanFSM->beamNo;
instPtr->linkLog.beamWidth = instPtr->log.lastBeamWidth;
instPtr->linkLog.beamAz = phyRef->antNrrwPattern[instPtr->scanFSM->beamNo].oaxis;
instPtr->linkLog.beamEl = phyRef->antNrrwPattern[instPtr->scanFSM->beamNo].raxis;
instPtr->linkLog.advTxCnt = (uint16_t)instPtr->log.advTxCnt;
instPtr->linkLog.advRecvCnt = (uint16_t)instPtr->log.advRecvCnt;
instPtr->linkLog.advCorrectCnt = (uint16_t)instPtr->log.advCorrectCnt;
instPtr->linkLog.cfmTxCnt = instPtr->log.cfmTxCnt;
instPtr->linkLog.cfmRecvCnt = instPtr->log.cfmRecvCnt;
instPtr->linkLog.cfmCorrectCnt = instPtr->log.cfmCorrectCnt;
instPtr->linkLog.svcTxCnt = instPtr->log.svcTxCnt;
instPtr->linkLog.svcRecvCnt = instPtr->log.svcRecvCnt;
instPtr->linkLog.svcCorrectCnt = instPtr->log.svcCorrectCnt;
instPtr->linkLog.timeDev = (instPtr->log.timeDev > INT32_MAX)
? INT32_MAX : ((instPtr->log.timeDev < INT32_MIN) ? INT32_MIN : (int32_t)instPtr->log.timeDev);
instPtr->linkLog.sendId = instPtr->log.txLog.dataId;
instPtr->linkLog.recvId = instPtr->log.rxLog.dataId;
SysMonitor_UpdateLinklayerLog(&(instPtr->linkLog));
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Steer antenna beam to specified node.
*
* @param instPtr a pointer to link layer descriptor instance
* @param nodeId destination node
*
* @return Corresponding frame length
* L2_FRAME_NONE_LEN if the frame type code cannot be recognized.
*
******************************************************************************/
int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId)
{
ASSERT(instPtr != NULL);
int32_t Status;
COORD myPos, dstPos, beamDir;
Status = L2_GetNodePos(instPtr->nodeList, nodeId, &dstPos);
if (Status != SUCCESS)
{
DBG_ERROR("Failed to retrieve position info of node %" PRIu8 ", remain last configuration.\n", nodeId);
return EPARAM;
}
myPos.x = instPtr->sysInfo.posX;
myPos.y = instPtr->sysInfo.posY;
myPos.z = instPtr->sysInfo.posZ;
// TODO Check data format
EULERANGLES attitudeEuler, antAttitudeEuler;
attitudeEuler.alpha = DEG2RAD(instPtr->sysInfo.pitch);
attitudeEuler.beta = DEG2RAD(instPtr->sysInfo.yaw);
attitudeEuler.gamma = DEG2RAD(instPtr->sysInfo.roll);
// FIXME: confirm date source.
antAttitudeEuler.alpha = DEG2RAD(0);
antAttitudeEuler.beta = DEG2RAD(0);
antAttitudeEuler.gamma = DEG2RAD(0);
// TODO Check data format
QUATERNION attitude, antAttitude;
attitude = Quaternion_FromeEulerAngles(attitudeEuler, EULERANGLES_XYZ);
antAttitude = Quaternion_FromeEulerAngles(antAttitudeEuler, EULERANGLES_XYZ);
// --- --- Algorithm --- ---
// TODO Check result validation
// Compute beam direction vector
beamDir = Coord_Sub(dstPos, myPos);
// Compute antenna attitude respect to ECEF
antAttitude = Quaternion_Mult(attitude, antAttitude);
// Convert beam direction vector to antenna coordinate
beamDir = Quaternion_Rotate(Quaternion_GeInverse(antAttitude), beamDir);
// Normalize
Coord_Normalize(&beamDir);
double oAxis, rAxis;
oAxis = RAD2DEG(atan2(beamDir.z, beamDir.y));
rAxis = RAD2DEG(acos(Coord_Dot(beamDir, COORD_X_AXIS)));
Status = Phy_SetBeamAngle(instPtr->config.phyInstPtr, oAxis, rAxis);
return Status;
}
/*****************************************************************************/
/**
* @brief Layer 2 setup next slot operation, update current operating frame.
*
* @param instPtr a pointer to linklayer instance
* @param txrxMode tx/rx state for next slot
* @param frameType frame type of next slot.
*
* @return SUCCESS/FAILURE
*
******************************************************************************/
int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType)
{
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
int32_t Status;
if (frameType < L2_SCAN_FRAME || frameType > L2_SVC_FRAME)
{
return FAILURE;
}
// logging
if (txrxMode == L2_TOR_TX)
{
instPtr->log.frameTx++;
switch (frameType)
{
case L2_ADV_FRAME:
instPtr->log.advTxCnt++;
break;
case L2_CFM_FRAME:
instPtr->log.cfmTxCnt++;
break;
case L2_SVC_FRAME:
instPtr->log.svcTxCnt++;
break;
default:
break;
}
}
else if (txrxMode == L2_TOR_RX)
{
instPtr->log.frameRx++;
switch (frameType)
{
case L2_ADV_FRAME:
instPtr->log.advRxCnt++;
break;
case L2_CFM_FRAME:
instPtr->log.cfmRxCnt++;
break;
case L2_SVC_FRAME:
instPtr->log.svcRxCnt++;
break;
default:
break;
}
}
#if _DEBUG_LEVEL >= 3
char *torStr = NULL;
char *frameStr = NULL;
switch (txrxMode)
{
case L2_TOR_SUSPEND:
torStr = "SUSPEND";
break;
case L2_TOR_TX:
torStr = "TX";
break;
case L2_TOR_RX:
torStr = "RX";
break;
}
switch (frameType)
{
case L2_SCAN_FRAME:
frameStr = "Scan";
break;
case L2_ADV_FRAME:
frameStr = "Advertisement";
break;
case L2_CFM_FRAME:
frameStr = "Confirm";
break;
case L2_SVC_FRAME:
frameStr = "Service";
break;
default:
frameStr = "UNKNOWN Frame";
break;
}
DBG_INFO("# Setup Next Slot # [%" PRIu32 "-%" PRIu32 "], %s, %s.\n",
instPtr->frameNum.next,
instPtr->slotNum.next,
torStr, frameStr);
#endif
// Update frame and tx/rx mode record.
// Frame types shift (last <- curr <- next)
L2_RcdShift(&(instPtr->frame), frameType);
L2_RcdShift(&(instPtr->tor), txrxMode);
TIME_WORD pullTime = {0, 0};
pullTime.int_part = TimeCtrl_GetIntCnt(instPtr->config.tmcInstPtr) + 1;
Status = Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL);
if (Status != SUCCESS)
{
DBG_ERROR("Physical set pull time failed, with error code: %" PRId32 "\n", Status);
}
PHY_TOR_TYPE tor;
switch (txrxMode)
{
case L2_TOR_SUSPEND:
tor = PHY_TOR_SUSPEND;
break;
case L2_TOR_TX:
tor = PHY_TOR_TX;
break;
case L2_TOR_RX:
tor = PHY_TOR_RX;
break;
default:
DBG_ERROR("Invalid txrx mode :%" PRId8 ".\n", txrxMode);
return EPARAM;
}
Status = Phy_SetupNextSlot(phyRef, tor, L2_L2frame2L1frame(frameType), instPtr->sendPktData);
if (Status != SUCCESS)
{
DBG_ERROR("Physical setup failed, with error code: %" PRId32 "\n", Status);
}
return Status;
}
/** @} LinkLayer_Main*/
/** @} LinkLayer*/
@@ -1,19 +1,21 @@
/*****************************************************************************/
/**
* Description: Header file for df linklayer functions
* @file link_layer.h
* @author FanHao ([email protected])
* @brief DF Linklayer header file.
* @version 0.1
* @date 2023-05-06
*
* Date: 2021-11-13 13:33
* LastEditTime: 2022-07-16 10:12
* Revisions: Rev 0.1
* History:
* [2022-07-16]: New branch for DiJian.
* [2021-11-23]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @defgroup LinkLayer
* @{
*/
#ifndef __LINK_LAYER_H_
#define __LINK_LAYER_H_
@@ -27,79 +29,97 @@
#include "../../system_monitor.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define AssertL2Event(instPtr, event) Linklayer_EventHandler(instPtr, event)
#define AssertL2Event(instPtr, event) (Linklayer_EventHandler((instPtr), (event)))
/**************************** Type Definitions *******************************/
/**
* @struct L2_CONFIG
* @brief A struct holds all linklayer initialization parameters
*/
typedef struct
{
L2_NODE_TYPE myType;
bool isInterHead;
uint8_t clustId;
uint8_t myId;
uint8_t headId;
uint8_t bkpHeadId;
uint8_t netScale;
PHY_INST *phyInstPtr;
TMC_INST *tmcInstPtr;
L2_NODE_TYPE myType; ///< node type
uint8_t clustId; ///< node cluster id
uint8_t myId; ///< node id
uint8_t headId; ///< head node id
uint8_t netScale; ///< net scale
PHY_INST *phyInstPtr; ///< pointer to system physical layer instance
TMC_INST *tmcInstPtr; ///< pointer to system timer controller layer instance
} L2_CONFIG;
/**
* @struct L2_LOG
* @brief A struct holds linklayer operating log
*/
typedef struct
{
uint32_t frameRx;
uint32_t frameTx;
uint32_t frameRecv;
uint32_t frameCorrect;
uint32_t frameRx; ///< total rx frame count
uint32_t frameTx; ///< total tx frame count
uint32_t frameRecv; ///< total received frame count
uint32_t frameCorrect; ///< total correctly received frame count
uint32_t advRxCnt;
uint32_t advTxCnt;
uint32_t advRecvCnt;
uint32_t advCorrectCnt;
uint32_t advRxCnt; ///< advertise rx frame count
uint32_t advTxCnt; ///< advertise tx frame count
uint32_t advRecvCnt; ///< advertise received frame count
uint32_t advCorrectCnt; ///< advertise correctly received frame count
uint32_t cfmRxCnt;
uint32_t cfmTxCnt;
uint32_t cfmRecvCnt;
uint32_t cfmCorrectCnt;
uint32_t cfmRxCnt; ///< confirm rx frame count
uint32_t cfmTxCnt; ///< confirm tx frame count
uint32_t cfmRecvCnt; ///< confirm received frame count
uint32_t cfmCorrectCnt; ///< confirm correctly received frame count
uint32_t svcRxCnt;
uint32_t svcTxCnt;
uint32_t svcRecvCnt;
uint32_t svcCorrectCnt;
uint32_t svcRxCnt; ///< service rx frame count
uint32_t svcTxCnt; ///< service tx frame count
uint32_t svcRecvCnt; ///< service received frame count
uint32_t svcCorrectCnt; ///< service correctly received frame count
int64_t timeDev; ///< last time deviation estimation result
uint8_t lastBeamWidth; ///< last beam width
uint32_t reconnectCnt; ///< reconnect trial count
PAYLOAD rxLog;
PAYLOAD txLog;
} L2_LOG;
/**
* @struct L2_INST
* @brief A linklayer instance
*/
typedef struct
{
L2_CONFIG config;
L2_NODE_INFO myInfo;
NODE_LIST *nodeList;
L2_SCHD_POOL *schdEventPool;
uint32_t netStartTime;
bool isEnable; // if the node is connected to the network
bool dataAvail; // if there is a valid received frame data in rx buffer
bool cxn2Net; // if the node is connected to the network
L2_RCD frameNum; // stores the last current and next frame number.
L2_RCD slotNum; // stores the last current and next slot number.
L2_RCD frame; // stores the last current and next link layer frame type.
L2_RCD tor; // stores the last current and next link layer tx/rx state.
L2_NODE_STATE mainState; // the main state of link layer state
L2_NODE_STATE nextState; // next state of link layer state, which will be applied to mainState every second.
L2_RTNE_CONFIG rtneConfig; // current routine table configuration and status.
L2_SCAN_FSM *scanFSM; // FSM of scan net (link set up)
L2_SVC_FSM *serviceFSM; // FSM of service net (data service)
uint8_t *sendPktData;
uint8_t *recvPktData;
L2_LOG log;
L2_CONFIG config; ///< linklayer configuration parameters
L2_NODE_INFO myInfo; ///< current node info
NODE_LIST *nodeList; ///< discovered node list
L2_SCHD_POOL *schdEventPool; ///< event schedule pool
uint32_t netStartTime; ///< network start time
bool isEnable; ///< indicates if the node is connected to the network
bool dataAvail; ///< indicates if there is a valid received frame data in rx buffer
bool cxn2Net; ///< indicates if the node is connected to the network
L2_RCD frameNum; ///< stores the last current and next frame number.
L2_RCD slotNum; ///< stores the last current and next slot number.
L2_RCD frame; ///< stores the last current and next link layer frame type.
L2_RCD tor; ///< stores the last current and next link layer tx/rx state.
L2_NODE_STATE mainState; ///< the main state of link layer state
L2_NODE_STATE nextState; ///< next state of link layer state, which will be applied to mainState every second.
L2_RTNE_CONFIG rtneConfig; ///< current routine table configuration and status.
L2_SCAN_FSM *scanFSM; ///< FSM of scan net (link set up)
L2_SVC_FSM *serviceFSM; ///< FSM of service net (data service)
uint8_t *sendPktData; ///< send data buffer
uint8_t *recvPktData; ///< received data buffer
L2_LOG log; ///< Linklayer operating log
// for system log
SYSINFO sysInfo;
SLOTLOG txSlotLog;
SLOTLOG rxSlotLog;
PRTCLLOG prtcLog;
SYSINFO sysInfo; ///< system info
LINKLOG linkLog; ///< linklayer log for system monitor
} L2_INST;
/************************** Variable Definitions *****************************/
extern L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalTable[L2_NORMAL_RTNE_PERIOD];
/************************** Function Prototypes ******************************/
// Main
/**
* @defgroup LinkLayer_Main
* @{
*/
int32_t Linklayer_Init(L2_INST **instPtr, const L2_CONFIG *config);
int32_t Linklayer_Reconfig(L2_INST *instPtr, const L2_CONFIG *config);
void Linklayer_Destroy(L2_INST *instPtr);
@@ -110,45 +130,72 @@ int32_t Linklayer_EventHandler(L2_INST *instPtr, const L2_EVENT *l2Event);
int32_t Linklayer_PktHandler(L2_INST *instPtr, L2_FRAME_TYPE frameType);
int32_t L2_SteerBeam2Node(L2_INST *instPtr, uint8_t nodeId);
int32_t L2_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType);
void L2_FrameStateUpdate(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr);
L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame);
/** @} LinkLayer_Main*/
// Scheduling Event
/**
* @defgroup LinkLayer_Framing
* @{
*/
void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void *chunk);
void L2_FrameGetChunk(uint8_t *frame, size_t offset, size_t bytes, void *chunk);
int32_t L2_CrcAppend(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType);
bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType);
/** @} LinkLayer_Framing*/
/**
* @defgroup LinkLayer_Scheduler
* @{
*/
void L2_EventPoolHandler(L2_INST *instPtr);
int32_t L2_ScheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo);
int32_t L2_ScheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots);
int32_t L2_RescheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNo, uint32_t slotNo);
int32_t L2_RescheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots);
/** @} LinkLayer_Scheduler*/
// Framing
void L2_FrameInsertChunk(uint8_t *frame, size_t offset, size_t bytes, const void *chunk);
void L2_FrameGetChunk(uint8_t *frame, size_t offset, size_t bytes, void *chunk);
int32_t L2_CrcAppend(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType);
bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType);
// Scanning
/**
* @defgroup LinkLayer_Scan
* @{
*/
int32_t L2_Scan_Init(L2_SCAN_FSM **scanFSMPtr);
void L2_Scan_RefreashScanTable(L2_INST *instPtr);
void L2_Scan_Reset(L2_SCAN_FSM *scanFSMPtr);
void L2_Scan_Destroy(L2_SCAN_FSM *scanFSMPtr);
int32_t L2_Scan_Proc(L2_INST *instPtr);
int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg);
int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *schedEntry);
/** @} LinkLayer_Scan*/
// Service
/**
* @defgroup LinkLayer_Service
* @{
*/
int32_t L2_Service_Init(L2_SVC_FSM **svcFSMPtr);
void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr);
void L2_Service_Destroy(L2_SVC_FSM *svcFSMPtr);
int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg);
int32_t L2_Service_Proc(L2_INST *instPtr);
int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *schedEntry);
/** @} LinkLayer_Service*/
// Miscellaneous
/**
* @defgroup LinkLayer_TimeSync
* @{
*/
int32_t L2_GetTimeDeviation(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool relative, int64_t *timeDev);
void L2_TimeAdjust(L2_INST *instPtr, const int64_t *timeDev);
/** @} LinkLayer_TimeSync*/
/**
* @defgroup LinkLayer_Utility
* @{
*/
uint8_t L2_GetNodeId(L2_INST *instPtr);
uint8_t L2_GetClusterId(L2_INST *instPtr);
uint8_t L2_GetHeadId(L2_INST *instPtr);
L2_NODE_TYPE L2_GetNodeType(L2_INST *instPtr);
L2_NODE_STATE L2_GetMainState(L2_INST *instPtr);
bool L2_isStarted(L2_INST *instPtr);
bool L2_isDataAvail(L2_INST *instPtr);
bool L2_isCxn2Net(L2_INST *instPtr);
uint32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType);
@@ -164,9 +211,10 @@ uint32_t L2_GetNextFrameNum(L2_INST *instPtr);
uint32_t L2_GetNextSlotNum(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetNextFrameType(L2_INST *instPtr);
L2_TOR_TYPE L2_GetNextTor(L2_INST *instPtr);
// Time syncronization
int32_t L2_TimeAlign(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool relative);
L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr);
L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame);
/** @} LinkLayer_Utility*/
#endif /* __LINK_LAYER_H_ */
/** @} LinkLayer*/
@@ -1,17 +1,19 @@
/*****************************************************************************/
/**
* Description: A brief description of this file
* @file link_layer_types.h
* @author FanHao ([email protected])
* @brief DF Linklayer types definition.
* @version 0.1
* @date 2023-05-06
*
* Date: 2022-08-28 22:53
* LastEditTime: 2022-08-29 00:45
* Revisions: Rev 0.0
* History:
* [2022-08-29]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @defgroup LinkLayer
* @{
*/
#ifndef __LINK_LAYER_DEF_H_
#define __LINK_LAYER_DEF_H_
@@ -22,7 +24,14 @@
#include "geometry/coord.h"
#include "geometry/quaternion.h"
#include "../phy_layer/phy_layer.h"
#ifndef EMULATION
#include "../config/app_config.h"
#endif
/************************** Constant Definitions *****************************/
/**
* @name Linklayer_Common_Constants
* @{
*/
// Common node ID definition
#define L2_BROADCAST_ID 0xFF
#define L2_NONE_ID 0
@@ -36,7 +45,7 @@
#define L2_FRAMENO_NONE 0
// Common number of slots definition
#define L2_SLOTS_PER_FRAME 200
#define L2_SLOTS_PER_FRAME 100
#define L2_SLOTS_PER_SUBFRAME 20
#define L2_NUM_SLOTS_NONE UINT32_MAX
@@ -45,9 +54,14 @@
#define L2_NUM_SLOTS_10MS 2
#define L2_NUM_SLOTS_5MS 1
#define L2_NUM_SLOTS_SKIP 0
/** @} Linklayer_Common_Constants*/
/**************************** Type Definitions *******************************/
/**
* @struct L2_RCD
* @brief Linklayer recode buffer
*/
typedef struct
{
uint32_t last;
@@ -55,7 +69,8 @@ typedef struct
uint32_t next;
} L2_RCD;
/** @name Tx/Rx mode code
/**
* @enum L2_TOR_TYPE
*/
typedef enum
{
@@ -64,7 +79,8 @@ typedef enum
L2_TOR_RX = 2
} L2_TOR_TYPE;
/** @name Prior information type definition
/**
* @enum L2_NODE_TYPE
*/
typedef enum
{
@@ -74,7 +90,8 @@ typedef enum
L2_NODE_BACKUP = 3
} L2_NODE_TYPE;
/** @name Node state type definition
/**
* @enum L2_NODE_STATE
*/
typedef enum
{
@@ -86,23 +103,24 @@ typedef enum
L2_SEEK_STATE = 5
} L2_NODE_STATE;
/** @name Node information type definition
* The following types define the detail node info which needed by the link layer.
/**
* @struct L2_NODE_INFO
* @brief Node information struct contains the detail node info which needed by the link layer.
*/
typedef struct
{
uint8_t nodeId;
uint8_t clustId;
uint8_t headId;
L2_NODE_TYPE nodeType;
uint8_t beamNo;
COORD pos;
COORD speed;
QUATERNION attitude;
uint8_t nodeId; ///< node ID
uint8_t clustId; ///< node cluster ID
uint8_t headId; ///< cluster head ID
L2_NODE_TYPE nodeType; ///< node type
uint8_t beamNo; ///< beam number to this node
COORD pos; ///< node position
COORD speed; ///< node speed
QUATERNION attitude; ///< node attitude
} L2_NODE_INFO;
/** @name L2 event enum
* A enum of L2 event types.
/**
* @enum L2_EVENT_TYPE
*/
typedef enum
{
@@ -120,17 +138,18 @@ typedef enum
L2_ROUTINE_UPDATE = 11
} L2_EVENT_TYPE;
/** @name L2 event
* A definition of L2 event instance.
/**
* @struct L2_EVENT
* @brief Linklayer event instance
*/
typedef struct
{
L2_EVENT_TYPE event;
void *msg;
L2_EVENT_TYPE event; ///< event type
void *msg; ///< event message (MUST be a heap item)
} L2_EVENT;
/** @name Slot types
* A definition of different slots.
/**
* @enum L2_SLOT_TYPE
*/
typedef enum
{
@@ -142,8 +161,8 @@ typedef enum
L2_SLOT_SERVICE = 5,
} L2_SLOT_TYPE;
/** @name Frame types
* A definition of different frame types.
/**
* @enum L2_FRAME_TYPE
*/
typedef enum
{
@@ -154,8 +173,8 @@ typedef enum
L2_SVC_FRAME = 4
} L2_FRAME_TYPE;
/** @name Frame types
* A definition of different frame types.
/**
* @enum L2_CRC_TYPE
*/
typedef enum
{
@@ -165,17 +184,21 @@ typedef enum
L2_CRC8_31 = 3
} L2_CRC_TYPE;
/** @name Schedule subtable entry
* A definition of Schedule subtable entry.
/**
* @struct L2_RTNE_TABLE_ENTRY
* @brief Linklayer routine table entry
*/
typedef struct
{
L2_SLOT_TYPE slotType : 8;
uint8_t slotSeq;
uint8_t src;
uint8_t dst;
L2_SLOT_TYPE slotType : 8; ///< slot type
uint8_t slotSeq; ///< slot sequence number
uint8_t src; ///< source node ID
uint8_t dst; ///< destination node ID
} L2_RTNE_TABLE_ENTRY;
/**
* @enum SCAN_STAGE
*/
typedef enum
{
L2_SCAN_NONE_STAGE = 0,
@@ -184,44 +207,56 @@ typedef enum
L2_SCAN_CFM_STAGE = 3
} SCAN_STAGE;
/** @name Scan procedure FSM
/**
* @struct L2_SCAN_FSM
* @brief Linklayer scan process FSM instance
*/
typedef struct
{
bool isLocked; // init acq done.
bool isAdvRecvd; // bm received.
bool isAckPending; // 2way acq done.
uint8_t scanCnt;
uint8_t beamNo;
uint8_t advTimeout;
uint8_t cfmTimeout;
SCAN_STAGE scanStage; // only for member node
bool isLocked; ///< indicates if init acq done(beam locked).
bool isAdvRecvd; ///< indicates if advertisement frame done(beam locked).
bool isAckPending; ///< indicates if confirm message acked
uint8_t scanCnt; ///< scan count
uint8_t advTimeout; ///< adv receive try count
uint8_t cfmTimeout; ///< cmf receive try count
SCAN_STAGE scanStage; ///< scan stage \n
/// only for member node
uint8_t beamNo; ///< locked beam number
uint8_t tableNo; ///< scan table index
} L2_SCAN_FSM;
/** @name Service procedure FSM
/**
* @struct L2_SVC_FSM
* @brief Linklayer service process FSM
*/
typedef struct
{
PAYLOAD rxLog;
PAYLOAD txLog;
uint32_t pktRecv;
uint32_t pktCorrect;
uint32_t txCnt; ///< tx frame count
uint32_t rxCnt; ///< rx frame count
uint32_t rxdCnt; ///< received frame count
#ifdef DATALINK_ENABLE_BERTEST
uint32_t bitTotal;
uint32_t bitError;
uint32_t bitTotal; ///< received bits count
uint32_t bitError; ///< error bits count
double lossRate; ///< packet loss rate
double errorRate; ///< bit error rate
#endif
} L2_SVC_FSM;
/**
* @struct L2_RTNE_CONFIG
* @brief Linklayer routine table configuration
*/
typedef struct
{
L2_RTNE_TABLE_ENTRY **rtneTable;
uint32_t rtnePrd;
L2_RTNE_TABLE_ENTRY *last;
L2_RTNE_TABLE_ENTRY *curr;
L2_RTNE_TABLE_ENTRY *next;
L2_RTNE_TABLE_ENTRY **rtneTable; ///< routine table
uint32_t rtnePrd; ///< period of routine table
L2_RTNE_TABLE_ENTRY *last; ///< last routine entry
L2_RTNE_TABLE_ENTRY *curr; ///< curent routine entry
L2_RTNE_TABLE_ENTRY *next; ///< next routine entry
} L2_RTNE_CONFIG;
/************************** Variable Definitions *****************************/
#endif /* __LINK_LAYER_DEF_H_ */
/** @} LinkLayer*/
@@ -1,17 +1,25 @@
/*****************************************************************************/
/**
* Description: Header of 814 linklayer messages
* @file msg_def.c
* @author FanHao ([email protected])
* @brief DF Linklayer message definition constants.
* @version 0.0
* @date 2023-05-06
*
* Date: 2022-07-14 00:08
* LastEditTime: 2022-07-14 22:52
* Revisions: Rev 0.0
* History:
* [2022-07-14]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @name LinkLayer_MSG_Constants
* @{
*/
#ifndef __L2_MSG_DEF_H_
#define __L2_MSG_DEF_H_
@@ -79,6 +87,10 @@
#define L2_MSG_CFM_SRC_SPEEDY_LEN 4
#define L2_MSG_CFM_SRC_SPEEDZ 28
#define L2_MSG_CFM_SRC_SPEEDZ_LEN 4
#define L2_MSG_CFM_PAYLOAD_ID 32
#define L2_MSG_CFM_PAYLOAD_ID_LEN 4
#define L2_MSG_CFM_PAYLOAD 36
#define L2_MSG_CFM_PAYLOAD_LEN 230
#define L2_MSG_CFM_CRC 266
#define L2_MSG_CFM_CRC_LEN 2
@@ -111,5 +123,8 @@
#define L2_MSG_SVC_CRC 266
#define L2_MSG_SVC_CRC_LEN 2
#endif //__L2_MSG_DEF_H_
/** @} LinkLayer_MSG_Constants*/
/** @} LinkLayer*/
@@ -1,19 +1,25 @@
/*****************************************************************************/
/**
* Description: Implementations of 814 linklayer local record.
* @file node_list.c
* @author FanHao ([email protected])
* @brief DF Linklayer node list implementation file
* @version 0.0
* @date 2023-05-06
*
* Date: 2022-07-14 00:08
* LastEditors: Fan Hao
* LastEditTime: 2022-07-14 22:52
* Revisions: Rev 0.0
* History:
* [2022-07-14]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_NodeList
* @{
*/
/***************************** Include Files *********************************/
#include <stdlib.h>
#include <string.h>
@@ -26,6 +32,10 @@
#include "error.h"
/***************** Macros (Inline Functions) Definitions *********************/
/**
* @brief Get the node list length
* @param list pointer to node list
*/
inline uint32_t L2_GetNodeListLen(NODE_LIST *list)
{
ASSERT(list != NULL);
@@ -34,7 +44,7 @@ inline uint32_t L2_GetNodeListLen(NODE_LIST *list)
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
static NODE_ENTRY util_entry;
static NODE_ENTRY util_entry = { 0 };
/************************** Function Prototypes ******************************/
/**
* @brief helper function to free node entry.
@@ -94,7 +104,7 @@ int32_t L2_NodeList_Init(NODE_LIST **list)
* @brief Clear all nodes in the node list, free allocated memory.
*
* @param list
*NONE
* @return NONE
*
******************************************************************************/
void L2_NodeList_Clear(NODE_LIST *list)
@@ -123,13 +133,17 @@ void L2_NodeList_Destroy(NODE_LIST *list)
* @param list
* @param nodeId
*
* @return Node entry
* @return Node entry \n
* NULL if node dose not exist.
*
******************************************************************************/
NODE_ENTRY *L2_GetNodeById(NODE_LIST *list, uint8_t nodeId)
{
ASSERT(list != NULL);
if (nodeId == L2_BROADCAST_ID || nodeId == L2_NONE_ID)
{
return NULL;
}
util_entry.nodeInfo.nodeId = nodeId;
clist_node_t *node = clist_find(list, &util_entry);
if (node == NULL)
@@ -150,7 +164,7 @@ NODE_ENTRY *L2_GetNodeById(NODE_LIST *list, uint8_t nodeId)
* @param nodeId
* @param nodeType
*
* @return SUCCESS Node was added successfully.
* @return SUCCESS Node was added successfully.\n
* Other Error occurred.(Node already exist, memory alloc error ect.)
*
******************************************************************************/
@@ -197,7 +211,7 @@ NODE_ENTRY *L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType
* @param list
* @param nodeId
*
* @return SUCCESS Node has been successfully deleted.
* @return SUCCESS Node has been successfully deleted.\n
* Other Node not exist.
*
******************************************************************************/
@@ -223,7 +237,7 @@ int32_t L2_DeleteNodeById(NODE_LIST *list, uint8_t nodeId)
* @param list
* @param nodeId
*
* @return true node in the list
* @return true node in the list\n
* false node not in the list
*
******************************************************************************/
@@ -241,7 +255,7 @@ bool L2_isNodeInList(NODE_LIST *list, uint8_t nodeId)
* @param nodeId
* @param dst A pointer to store distance.
*
* @return SUCCESS distance has been successfully store in dst
* @return SUCCESS distance has been successfully store in dst\n
* FAILURE Node dose not exit.
*
******************************************************************************/
@@ -269,7 +283,7 @@ int32_t L2_GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double *d
* @param nodeId
* @param newPos A structure stores the corresponding node position info.
*
* @return SUCCESS update successfully.
* @return SUCCESS update successfully.\n
* FAILURE node not exist.
*
******************************************************************************/
@@ -296,7 +310,7 @@ int32_t L2_UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos)
* @param nodeId
* @param newPos A structure stores the corresponding node position info.
*
* @return SUCCESS update successfully.
* @return SUCCESS update successfully.\n
* FAILURE node not exist.
*
******************************************************************************/
@@ -323,7 +337,7 @@ int32_t L2_GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *pos)
* @param nodeId
* @param newSpeed A structure stores the corresponding node speed info.
*
* @return SUCCESS update successfully.
* @return SUCCESS update successfully.\n
* FAILURE node not exist.
*
******************************************************************************/
@@ -350,7 +364,7 @@ int32_t L2_UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpee
* @param nodeId
* @param newSpeed A structure stores the corresponding node speed info.
*
* @return SUCCESS update successfully.
* @return SUCCESS update successfully.\n
* FAILURE node not exist.
*
******************************************************************************/
@@ -376,7 +390,7 @@ int32_t L2_GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed)
* @param nodeId
* @param devi
*
* @return SUCCESS update successfully.
* @return SUCCESS update successfully.\n
* FAILURE Node not exist.
*
******************************************************************************/
@@ -428,7 +442,7 @@ int32_t L2_IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc)
* @param list
* @param nodeId
*
* @return SUCCESS TTL has been successfully cleared.
* @return SUCCESS TTL has been successfully cleared.\n
* FAILURE Node not exist.
*
******************************************************************************/
@@ -482,7 +496,7 @@ int32_t L2_GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl)
* @param operation A pointer to a function handled "NODE_ENTRY*" as input
* which defines the operations need to be apply.
*
* @return SUCCESS Operations has been applied successfully to all nodes.
* @return SUCCESS Operations has been applied successfully to all nodes.\n
* Other Error occurred.
*
******************************************************************************/
@@ -541,3 +555,7 @@ int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *))
clist_iterator_destroy(iter);
return SUCCESS;
}
/** @} LinkLayer_NodeList*/
/** @} LinkLayer*/
@@ -1,19 +1,27 @@
/*****************************************************************************/
/**
* Description: Header of 814 linklayer local record.
* @file node_list.h
* @author FanHao ([email protected])
* @brief DF Linklayer node list header file
* @version 0.0
* @date 2023-05-06
*
* Date: 2022-07-14 00:08
* LastEditors: Fan Hao
* LastEditTime: 2022-07-14 22:52
* Revisions: Rev 0.0
* History:
* [2022-07-14]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @defgroup LinkLayer_NodeList
* @{
*/
/***************************** Include Files *********************************/
#ifndef NODE_LIST_H_
#define NODE_LIST_H_
@@ -29,7 +37,11 @@
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
typedef struct NODE_LIST_ENTRY
/**
* @struct NODE_ENTRY
* @brief Linklayer discovered node list node entry
*/
typedef struct
{
L2_NODE_INFO nodeInfo;
uint32_t ttlCnt;
@@ -62,3 +74,6 @@ int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)
int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *));
#endif /* NODE_LIST_H_ */
/** @} LinkLayer_NodeList*/
/** @} LinkLayer*/
@@ -1,17 +1,26 @@
/*****************************************************************************/
/**
* Description: Time allocations for df datalink,
* Date: 2022-07-16 17:05
* LastEditTime: 2022-07-16 17:05
* Revisions: Rev 0.1
* History:
* [2021-11-13]: Initial version.
* @file routine_table.c
* @author FanHao ([email protected])
* @brief DF Linklayer node list implementation file
* @version 0.0
* @date 2023-05-06
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @name RoutineTable
* @{
*/
#include <inttypes.h>
#include "link_layer.h"
#include "link_layer_types.h"
@@ -38,6 +47,7 @@ L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = {
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
// SubFrame 1
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
@@ -59,6 +69,7 @@ L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = {
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
// SubFrame 2
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
@@ -80,6 +91,7 @@ L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = {
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
// SubFrame 3
{L2_SLOT_SCAN, 0x00, 0x01, 0xFF},
{L2_SLOT_SCAN, 0x01, 0x01, 0xFF},
@@ -101,132 +113,28 @@ L2_RTNE_TABLE_ENTRY intraScanSubT[L2_SLOTS_PER_FRAME] = {
{L2_SLOT_ADVERTISE, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 4
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
// SubFrame 5
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
// SubFrame 6
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
// SubFrame 7
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
// SubFrame 8
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
// SubFrame 9
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x01, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x02, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x03, 0xFF, 0x01},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x00, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x01, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x02, 0x01, 0xFF},
{L2_SLOT_CONFIRM, 0x03, 0x01, 0xFF},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
};
L2_RTNE_TABLE_ENTRY normalSub[L2_SLOTS_PER_FRAME] = {
@@ -235,220 +143,110 @@ L2_RTNE_TABLE_ENTRY normalSub[L2_SLOTS_PER_FRAME] = {
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 1
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 2
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 3
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
// SubFrame 4
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
// SubFrame 5
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
// SubFrame 6
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
// SubFrame 7
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
// SubFrame 8
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
// SubFrame 9
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x00, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x01, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x02, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x03, 0x01, 0x02},
{L2_SLOT_SERVICE, 0x00, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x01, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x02, 0x02, 0x01},
{L2_SLOT_SERVICE, 0x03, 0x02, 0x01},
{L2_SLOT_IDLE, 0x00, 0x00, 0x00},
};
L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD] =
@@ -460,3 +258,6 @@ L2_RTNE_TABLE_ENTRY *normalTable[L2_NORMAL_RTNE_PERIOD] =
{
normalSub
};
/** @} RoutineTable*/
/** @} LinkLayer*/
+349 -114
View File
@@ -1,18 +1,24 @@
/*****************************************************************************/
/**
* Description: Implementations of df linklayer scan net.
* @file scan.c
* @author FanHao ([email protected])
* @brief DF Linklayer scan implementation file.
* @version 0.1
* @date 2023-05-06
*
* Date: 2021-11-10 19:04
* LastEditTime: 2022-07-16 17:04
* Revisions: Rev 0.1
* History:
* [2022-07-16]: New branch for DiJian.
* [2021-11-10]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Scan
* @{
*/
/***************************** Include Files *********************************/
#include <string.h>
@@ -26,15 +32,97 @@
/************************** Constant Definitions *****************************/
#define ADV_LISTEN_TIMEOUT 40
#define CFM_LISTEN_TIMEOUT 25
#define CFM_LISTEN_TIMEOUT 5
#define ADV_FRAME_SLOTS 4
#define CFM_FRAME_SLOTS 4
#define CFM_FRAME_SLOTS 5
/***************** Macros (In-line Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
// Pair by regex
// Regex: ((\{\.oaxis = [0-9]+[ ,]+\.raxis = [0-9]+[ ]*\}, ){2})
PHY_ANT_ANGLE antNrrwPattern_0[L1_NUM_ANT_NRRW_PATTERN] =
{
{.oaxis = 0 , .raxis = 0 },
{.oaxis = 139, .raxis = 2225},
{.oaxis = 152, .raxis = 850 },
{.oaxis = 138, .raxis = 3155},
{.oaxis = 159, .raxis = 1680},
{.oaxis = 168, .raxis = 285 },
{.oaxis = 195, .raxis = 2630},
{.oaxis = 211, .raxis = 1204},
{.oaxis = 225, .raxis = 3429},
{.oaxis = 249, .raxis = 2022},
{.oaxis = 272, .raxis = 629 },
{.oaxis = 265, .raxis = 2934},
{.oaxis = 277, .raxis = 1499},
{.oaxis = 289, .raxis = 124 },
{.oaxis = 300, .raxis = 2349},
{.oaxis = 311, .raxis = 959 },
{.oaxis = 321, .raxis = 3199},
{.oaxis = 331, .raxis = 1824},
{.oaxis = 341, .raxis = 389 },
{.oaxis = 351, .raxis = 2674},
{.oaxis = 360, .raxis = 1268},
{.oaxis = 364, .raxis = 3483},
{.oaxis = 378, .raxis = 2118},
{.oaxis = 387, .raxis = 733 },
{.oaxis = 416, .raxis = 3028},
{.oaxis = 404, .raxis = 1623},
{.oaxis = 433, .raxis = 248 },
{.oaxis = 421, .raxis = 2473},
{.oaxis = 429, .raxis = 1098},
{.oaxis = 437, .raxis = 3303},
{.oaxis = 445, .raxis = 1948},
{.oaxis = 443, .raxis = 543 },
{.oaxis = 450, .raxis = 2828},
{.oaxis = 448, .raxis = 1422},
{.oaxis = 455, .raxis = 47 },
{.oaxis = 453, .raxis = 2272},
{.oaxis = 450, .raxis = 897 }
};
PHY_ANT_ANGLE antNrrwPattern_1[L1_NUM_ANT_NRRW_PATTERN] =
{
{.oaxis = 0 , .raxis = 0 },
{.oaxis = 139, .raxis = 1155},
{.oaxis = 152, .raxis = 3380},
{.oaxis = 138, .raxis = 2085},
{.oaxis = 159, .raxis = 610 },
{.oaxis = 168, .raxis = 2815},
{.oaxis = 195, .raxis = 1560},
{.oaxis = 211, .raxis = 134 },
{.oaxis = 225, .raxis = 2359},
{.oaxis = 249, .raxis = 952 },
{.oaxis = 272, .raxis = 3159},
{.oaxis = 265, .raxis = 1864},
{.oaxis = 277, .raxis = 429 },
{.oaxis = 289, .raxis = 2654},
{.oaxis = 300, .raxis = 1279},
{.oaxis = 311, .raxis = 3489},
{.oaxis = 321, .raxis = 2129},
{.oaxis = 331, .raxis = 754 },
{.oaxis = 341, .raxis = 2919},
{.oaxis = 351, .raxis = 1604},
{.oaxis = 360, .raxis = 198 },
{.oaxis = 364, .raxis = 2413},
{.oaxis = 378, .raxis = 1048},
{.oaxis = 387, .raxis = 3263},
{.oaxis = 416, .raxis = 1958},
{.oaxis = 404, .raxis = 553 },
{.oaxis = 433, .raxis = 2778},
{.oaxis = 421, .raxis = 1403},
{.oaxis = 429, .raxis = 28 },
{.oaxis = 437, .raxis = 2233},
{.oaxis = 445, .raxis = 878 },
{.oaxis = 443, .raxis = 3073},
{.oaxis = 450, .raxis = 1758},
{.oaxis = 448, .raxis = 352 },
{.oaxis = 455, .raxis = 2577},
{.oaxis = 453, .raxis = 1202},
{.oaxis = 450, .raxis = 3427},
};
/************************** Function Prototypes ******************************/
static void LockStateUpdate(L2_SCAN_FSM *scanFsmPtr, bool state);
static void AdvRecvStateUpdate(L2_SCAN_FSM *scanFsmPtr, bool state);
@@ -94,7 +182,7 @@ static void PendCfmAck(L2_SCAN_FSM *scanFsmPtr)
******************************************************************************/
static void StageUpdate(L2_SCAN_FSM *scanFsmPtr, SCAN_STAGE newStage)
{
ASSERT(newStage >= L2_SCAN_NONE_STAGE && newStage <= L2_SCAN_CFM_STAGE);
ASSERT((newStage >= L2_SCAN_NONE_STAGE) && (newStage <= L2_SCAN_CFM_STAGE));
DBG_INFO("ScanNet current stage: %" PRIu8 " -> ScanNet new stage: %" PRIu8 " \n",
scanFsmPtr->scanStage, newStage);
scanFsmPtr->scanStage = newStage;
@@ -112,26 +200,43 @@ static void StageUpdate(L2_SCAN_FSM *scanFsmPtr, SCAN_STAGE newStage)
static int32_t Scan_InitScanHandler(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
DBG_INFO("** Net-Setup - InitScan Procedure (Attempts: %" PRIu8 ")**\n", scanFsmPtr->scanCnt);
if (scanFsmPtr->scanCnt == 0)
{
// Update scan beam table
L2_Scan_RefreashScanTable(instPtr);
}
else if (Phy_IsFrameDetected(phyRef))
{
// last scan beam number
scanFsmPtr->beamNo = Phy_LastScanBeamNo(phyRef);
// Update scan beam table
L2_Scan_RefreashScanTable(instPtr);
}
if (scanFsmPtr->isLocked == true)
{
StageUpdate(scanFsmPtr, L2_SCAN_ADV_STAGE);
/* Antenna setting (reserved.) */
scanFsmPtr->beamNo = Phy_LastScanBeamNo(phyRef);
Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_ADV_FRAME);
StageUpdate(scanFsmPtr, L2_SCAN_ADV_STAGE);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
} /* Otherwise remain L2_SCAN_INIT_STAGE */
else
{
/* Antenna setting (reserved.) */
/* Antenna steering (reserved, automatically accomplished by physical layer) */
Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_SCAN_FRAME);
scanFsmPtr->scanCnt++;
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Member node scan net BmAdvt stage handler.
*
@@ -143,16 +248,36 @@ static int32_t Scan_InitScanHandler(L2_INST *instPtr)
******************************************************************************/
static int32_t Scan_AdvHandler(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
PHY_INST *phyRef = instPtr->config.phyInstPtr;
TMC_INST *tmcRef = instPtr->config.tmcInstPtr;
DBG_INFO("** Net-Setup - Advertisement Procedure (Timeout: %" PRIu8 ") **\n", scanFsmPtr->advTimeout);
// if received a valid bm frame.
if (scanFsmPtr->isAdvRecvd == true)
{
scanFsmPtr->advTimeout = 0; /* reset listen counter. */
DBG_INFO("Received Adv frame, skipping 10ms for turn around...\n");
// TODO: check functionality.
// last scan beam number
scanFsmPtr->beamNo = Phy_LastScanBeamNo(phyRef);
// reset listen counter.
scanFsmPtr->advTimeout = 0;
// Update scan stage
StageUpdate(scanFsmPtr, L2_SCAN_CFM_STAGE);
// start a confirm frame reception if in the target slot
if ((TimeCtrl_GetIntCnt(tmcRef) + 1) % CFM_FRAME_SLOTS == 0)
{
// using pull mode to receive confirm frame
// since first time sync procedure is accomplished in ADV stage.
(void)Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_16);
(void)Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
(void)Phy_SetMode(phyRef, PHY_MODE_PULL);
(void)L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_CFM_FRAME);
scanFsmPtr->cfmTimeout++; // increase counter.
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
}
// otherwise skip...
return SUCCESS;
}
// no valid bm frame was received.
@@ -161,16 +286,20 @@ static int32_t Scan_AdvHandler(L2_INST *instPtr)
/* if time out reached, go back to init scan stage. */
if (scanFsmPtr->advTimeout > ADV_LISTEN_TIMEOUT)
{
/* Antenna setting (reserved.) */
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_SCAN_FRAME);
/* Antenna steering (reserved, automatically accomplished by physical layer) */
(void)Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
(void)L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_SCAN_FRAME);
DBG_WARNING("Adv timeout, restart net scan from L2_SCAN_INIT_STAGE.\n");
L2_Scan_Reset(scanFsmPtr);
(void)L2_Scan_Reset(scanFsmPtr);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
}
else
{
/* Antenna setting (reserved.) */
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_ADV_FRAME);
/* Antenna steering (reserved, automatically accomplished by physical layer) */
(void)Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
(void)L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_ADV_FRAME);
scanFsmPtr->advTimeout++;
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
}
return SUCCESS;
}
@@ -187,7 +316,9 @@ static int32_t Scan_AdvHandler(L2_INST *instPtr)
******************************************************************************/
static int32_t Scan_CfmHandler(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
PHY_INST *phyRef = instPtr->config.phyInstPtr;
DBG_INFO("** Net-Setup - Confirm Procedure (Timeout: %" PRIu8 ") **\n", scanFsmPtr->cfmTimeout);
// 2 way acq failed, back to init stage.
@@ -201,9 +332,12 @@ static int32_t Scan_CfmHandler(L2_INST *instPtr)
{
// using pull mode to receive confirm frame
// since first time sync procedure is accomplished in ADV stage.
Phy_SetMode(instPtr->config.phyInstPtr, PHY_MODE_PULL);
L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_CFM_FRAME);
(void)Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_16);
(void)Phy_SetBeamNo(phyRef, scanFsmPtr->beamNo, PHY_ANT_BEAM_16);
(void)Phy_SetMode(phyRef, PHY_MODE_PULL);
(void)L2_SetupNextSlot(instPtr, L2_TOR_RX, L2_CFM_FRAME);
scanFsmPtr->cfmTimeout++; // increase counter.
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
}
return SUCCESS;
}
@@ -225,12 +359,13 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
int32_t Status;
uint32_t dataChunk;
uint8_t *buff = instPtr->sendPktData;
if(type < L2_ADV_FRAME || type > L2_CFM_FRAME)
if ((type < L2_ADV_FRAME) || (type > L2_CFM_FRAME))
{
DBG_ERROR("Unexpected frame type: %" PRId8 ".\n", type);
return EPARAM;
}
// Common section of link layer package
dataChunk = L2_GetNextFrameNum(instPtr);
L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &dataChunk);
dataChunk = L2_GetNextSlotNum(instPtr);
@@ -278,6 +413,23 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDY, L2_MSG_CFM_SRC_SPEEDY_LEN, &(instPtr->sysInfo.vY));
L2_FrameInsertChunk(buff, L2_MSG_CFM_SRC_SPEEDZ, L2_MSG_CFM_SRC_SPEEDZ_LEN, &(instPtr->sysInfo.vZ));
// Packing extra payload
uint32_t dataId;
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_GetSendPayload(buff + L2_MSG_CFM_PAYLOAD, &dataId, PAYLOAD_LEN_FLJ_TX);
}
else
{
SysMonitor_GetSendPayload(buff + L2_MSG_CFM_PAYLOAD, &dataId, PAYLOAD_LEN_LJ_TX);
}
L2_FrameInsertChunk(buff, L2_MSG_CFM_PAYLOAD_ID, L2_MSG_CFM_PAYLOAD_ID_LEN, &dataId);
if (dataId == DATA_ID_NONE)
{
memset(buff + L2_MSG_CFM_PAYLOAD, 0xAA, L2_MSG_CFM_PAYLOAD_LEN);
}
// Append CRC
Status = L2_CrcAppend(buff, L2_CMF_PACK_LEN - L2_MSG_CFM_CRC_LEN, L2_MSG_CFM_CRC, L2_CRC16_1021);
if (Status != SUCCESS)
@@ -285,6 +437,10 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
DBG_ERROR("Fail to append CRC, error code: %" PRId32 ".\n", Status);
return Status;
}
// Logging...
memcpy(instPtr->log.txLog.data, buff, L2_CMF_PACK_LEN);
instPtr->log.txLog.dataId = dataId;
break;
}
default:
@@ -296,68 +452,11 @@ static int32_t ScanMsg_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Initialize scan FSM.
*
* @param instPtr
*
* @return
*
******************************************************************************/
int32_t L2_Scan_Init(L2_SCAN_FSM **scanFSMPtr)
{
ASSERT(scanFSMPtr != NULL);
*scanFSMPtr = (L2_SCAN_FSM *)malloc(sizeof(L2_SCAN_FSM));
if (*scanFSMPtr == NULL)
{
DBG_ERROR("Failed to allocate memory for scanFsmPtr.\n");
return ENOMEM;
}
L2_Scan_Reset(*scanFSMPtr);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Reset ScanNet FSM
*
* @param scanFsmPtr a pointer to scan net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Scan_Reset(L2_SCAN_FSM *scanFSMPtr)
{
ASSERT(scanFSMPtr != NULL);
scanFSMPtr->isLocked = false;
scanFSMPtr->isAdvRecvd = false;
scanFSMPtr->isAckPending = false;
scanFSMPtr->scanCnt = 0;
scanFSMPtr->beamNo = 0;
scanFSMPtr->advTimeout = 0;
scanFSMPtr->cfmTimeout = 0;
scanFSMPtr->scanStage = L2_SCAN_NONE_STAGE;
}
/*****************************************************************************/
/**
* @brief Destroy ScanNet FSM, free memory
*
* @param scanFsmPtr a pointer to scan net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Scan_Destroy(L2_SCAN_FSM *scanFSMPtr)
{
free(scanFSMPtr);
}
/*****************************************************************************/
/**
* @brief Scan net packet handler.
*
* @param instPtr a pointer to linklayer layer instance
* @param msg A pointer to frame data buffer.
*
* @return
@@ -369,15 +468,19 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
ASSERT(msg != NULL);
int32_t Status;
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
L2_FRAME_TYPE frameType = L2_GetLastOptFrameType(instPtr);
L2_FRAME_TYPE frameType = L2_NONE_FRAME;
L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType);
switch (frameType)
{
case L2_SCAN_FRAME:
LockStateUpdate(scanFsmPtr, true);
StageUpdate(scanFsmPtr, L2_SCAN_ADV_STAGE);
case L2_ADV_FRAME:
{
if (instPtr->config.myType == L2_NODE_HEAD)
if (L2_GetLastOptFrameType(instPtr) == L2_SCAN_FRAME)
{
LockStateUpdate(scanFsmPtr, true);
StageUpdate(scanFsmPtr, L2_SCAN_ADV_STAGE);
}
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
DBG_ERROR("Unexpected call from head node, only member Node can handle L2_SCAN_FRAME and L2_ADV_FRAME.\n");
Status = EUNEXP;
@@ -405,13 +508,12 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
node->nodeInfo.pos.y = (double)nodePos;
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_POSZ, L2_MSG_ADV_SRC_POSZ_LEN, &nodePos);
node->nodeInfo.pos.z = (double)nodePos;
node->nodeInfo.beamNo = Phy_LastScanBeamNo(instPtr->config.phyInstPtr);
// Reset node ttl
node->ttlCnt = 0;
if (L2_isCxn2Net(instPtr) == false)
{
uint32_t netstartTime, frameNum, slotNum = 0;
uint32_t netstartTime;
// Update net start time.
L2_FrameGetChunk(msg, L2_MSG_ADV_SRC_NETSTART_TIME, L2_MSG_ADV_SRC_NETSTART_TIME_LEN, &netstartTime);
L2_EVENT netSetupDoneEvent = {
@@ -419,12 +521,20 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
.msg = &netstartTime};
AssertL2Event(instPtr, &netSetupDoneEvent);
// Time sync.
// Calculate time deviation
uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
// TODO: Check
L2_TimeAlign(instPtr, frameNum, slotNum, true);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS)
{
DBG_ERROR("Failed to compute time deviation.\n")
break;
}
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
// trigger flag
AdvRecvStateUpdate(scanFsmPtr, true);
Status = SUCCESS;
@@ -465,6 +575,17 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
// Reset node ttl
node->ttlCnt = 0;
// Calculate time deviation
uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS)
{
DBG_ERROR("Failed to compute time deviation.\n")
break;
}
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
// check if net setup finished.
@@ -485,9 +606,11 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
};
newRtneConfig.rtneTable = initTable;
newRtneConfig.rtnePrd = ARRAY_SIZE(initTable);
AssertL2Event(instPtr, &rtneUpEvent);
(void)AssertL2Event(instPtr, &rtneUpEvent);
}
PendCfmAck(instPtr->scanFSM);
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
}
else
{
@@ -499,9 +622,27 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
L2_NODE_STATE newState = L2_NORMAL_STATE;
l2Event.event = L2_EV_MAIN_STATE_UPDATE;
l2Event.msg = &newState;
AssertL2Event(instPtr, &l2Event);
(void)AssertL2Event(instPtr, &l2Event);
}
}
// Get data payload
uint32_t dataId;
L2_FrameGetChunk(msg, L2_MSG_CFM_PAYLOAD_ID, L2_MSG_CFM_PAYLOAD_ID_LEN, &dataId);
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_UpdateRecvPayload(msg + L2_MSG_CFM_PAYLOAD, dataId, PAYLOAD_LEN_FLJ_RX);
}
else
{
SysMonitor_UpdateRecvPayload(msg + L2_MSG_CFM_PAYLOAD, dataId, PAYLOAD_LEN_LJ_RX);
}
// Logging...
memcpy(instPtr->log.rxLog.data, msg, L2_CMF_PACK_LEN);
instPtr->log.rxLog.dataId = dataId;
Status = SUCCESS;
break;
}
@@ -513,6 +654,90 @@ int32_t L2_Scan_PktHandler(L2_INST *instPtr, uint8_t *msg)
return Status;
}
/*****************************************************************************/
/**
* @brief Initialize scan FSM.
*
* @param instPtr
*
* @return
*
******************************************************************************/
int32_t L2_Scan_Init(L2_SCAN_FSM **scanFSMPtr)
{
ASSERT(scanFSMPtr != NULL);
*scanFSMPtr = (L2_SCAN_FSM *)malloc(sizeof(L2_SCAN_FSM));
if (*scanFSMPtr == NULL)
{
DBG_ERROR("Failed to allocate memory for scanFsmPtr.\n");
return ENOMEM;
}
L2_Scan_Reset(*scanFSMPtr);
(*scanFSMPtr)->beamNo = 0;
(*scanFSMPtr)->tableNo = 0;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Reset ScanNet FSM
*
* @param scanFsmPtr a pointer to scan net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Scan_Reset(L2_SCAN_FSM *scanFSMPtr)
{
ASSERT(scanFSMPtr != NULL);
scanFSMPtr->isLocked = false;
scanFSMPtr->isAdvRecvd = false;
scanFSMPtr->isAckPending = false;
scanFSMPtr->scanCnt = 0;
scanFSMPtr->advTimeout = 0;
scanFSMPtr->cfmTimeout = 0;
scanFSMPtr->scanStage = L2_SCAN_NONE_STAGE;
}
/*****************************************************************************/
/**
* @brief Destroy ScanNet FSM, free memory
*
* @param scanFsmPtr a pointer to scan net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Scan_Destroy(L2_SCAN_FSM *scanFSMPtr)
{
free(scanFSMPtr);
}
/*****************************************************************************/
/**
* @brief Refresh scan beam table.
*
* @param instPtr a pointer to linklayer layer instance
*
* @return NONE
*
******************************************************************************/
void L2_Scan_RefreashScanTable(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
L2_SCAN_FSM *scanFsmPtr = instPtr->scanFSM;
PHY_INST *phyRef = instPtr->config.phyInstPtr;
if (scanFsmPtr->tableNo == 0)
{
Phy_SetBeamTable(phyRef, antNrrwPattern_0, scanFsmPtr->beamNo);
scanFsmPtr->tableNo = 1;
}
else
{
Phy_SetBeamTable(phyRef, antNrrwPattern_1, scanFsmPtr->beamNo);
scanFsmPtr->tableNo = 0;
}
}
/*****************************************************************************/
/**
@@ -571,7 +796,8 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
{
ASSERT(instPtr != NULL);
L2_TOR_TYPE torState;
int32_t Status;
const NODE_ENTRY *commNode;
PHY_INST *phyRef = instPtr->config.phyInstPtr;
DBG_INFO("-------- Scan Routine --------\n");
if (rtneEntry->slotSeq != 0)
@@ -584,15 +810,25 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
if (rtneEntry->dst == L2_GetNodeId(instPtr) || rtneEntry->dst == L2_BROADCAST_ID)
{
torState = L2_TOR_RX;
commNode = L2_GetNodeById(instPtr->nodeList, rtneEntry->src);
}
else if (rtneEntry->src == L2_GetNodeId(instPtr) || rtneEntry->src == L2_BROADCAST_ID)
{
torState = L2_TOR_TX;
commNode = L2_GetNodeById(instPtr->nodeList, rtneEntry->dst);
}
else
{
torState = L2_TOR_SUSPEND;
}
// Setup antenna beam
Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_16);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
if (commNode != NULL)
{
(void)Phy_SetBeamNo(phyRef, commNode->nodeInfo.beamNo, PHY_ANT_BEAM_16);
}
}
else
{
@@ -608,6 +844,9 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
{
torState = L2_TOR_SUSPEND;
}
// Setup antenna beam
(void)Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_120);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_120;
}
switch (rtneEntry->slotType)
@@ -616,10 +855,9 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD && torState == L2_TOR_TX)
{
DBG_ERROR("Only head node can send init-scan Frame.\n");
Status = FAILURE;
goto routine_err;
return FAILURE;
}
L2_SetupNextSlot(instPtr, torState, L2_SCAN_FRAME);
(void)L2_SetupNextSlot(instPtr, torState, L2_SCAN_FRAME);
break;
case L2_SLOT_ADVERTISE:
@@ -628,18 +866,16 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
DBG_ERROR("Only head node can send ADV Frame.\n");
Status = FAILURE;
goto routine_err;
return FAILURE;
}
memset(instPtr->sendPktData, 0xAA, L2_PACK_LEN_MAX);
if (ScanMsg_Packing(instPtr, L2_ADV_FRAME, rtneEntry->dst) != SUCCESS)
{
Status = FAILURE;
goto routine_err;
return FAILURE;
}
}
/* Antenna setting (reserved.) */
L2_SetupNextSlot(instPtr, torState, L2_ADV_FRAME);
(void)L2_SetupNextSlot(instPtr, torState, L2_ADV_FRAME);
break;
case L2_SLOT_CONFIRM:
@@ -656,19 +892,18 @@ int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
memset(instPtr->sendPktData, 0xAA, L2_PACK_LEN_MAX);
if (ScanMsg_Packing(instPtr, L2_CFM_FRAME, rtneEntry->dst) != SUCCESS)
{
Status = FAILURE;
goto routine_err;
return FAILURE;
}
}
/* Antenna setting (reserved.) */
L2_SetupNextSlot(instPtr, torState, L2_CFM_FRAME);
(void)L2_SetupNextSlot(instPtr, torState, L2_CFM_FRAME);
break;
default:
DBG_ERROR("Cannot start a routine for slot type [%" PRId8 "] properly.\n", rtneEntry->slotType);
Status = FAILURE;
goto routine_err;
return FAILURE;
}
return SUCCESS;
routine_err:
return Status;
}
/** @} LinkLayer_Scan*/
/** @} LinkLayer*/
@@ -1,19 +1,24 @@
/*****************************************************************************/
/**
* Description: Event scheduling implementation
* @file schdevent.c
* @author FanHao ([email protected])
* @brief DF Linklayer Event scheduling implementation file.
* @version 0.1
* @date 2023-05-06
*
* Date: 2023-12-21 13:32
* LastEditors: Fan Hao
* LastEditTime: 2023-12-21 13:32
* Revisions: Rev 0.0
* History:
* [2023-12-21]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Scheduler
* @{
*/
/***************************** Include Files *********************************/
#include <stdlib.h>
#include "schdevent.h"
@@ -360,7 +365,7 @@ void L2_EventPoolHandler(L2_INST *instPtr)
if (event->schdFrame == L2_GetCurrentFrameNum(instPtr) && event->schdSlot == L2_GetCurrentSlotNum(instPtr))
{
DBG_INFO("Asserting scheduled event [%" PRIu32 "].\n", event->eventId);
AssertL2Event(instPtr, &(event->l2Event));
(void)AssertL2Event(instPtr, &(event->l2Event));
if (event->isVolatile == true)
{
DBG_INFO("Deleting scheduled event [%" PRIu32 "], since it is volatile.\n", event->eventId);
@@ -428,3 +433,6 @@ inline bool L2_isEventScheduled(const L2_SCHD_EVENT *schdEvent)
ASSERT(schdEvent != NULL);
return schdEvent->isSchd;
}
/** @} LinkLayer_Scheduler*/
/** @} LinkLayer*/
@@ -1,18 +1,24 @@
/*****************************************************************************/
/**
* Description: Event scheduling implementation
* @file schdevent.c
* @author FanHao ([email protected])
* @brief DF Linklayer Event scheduling header file.
* @version 0.1
* @date 2023-05-06
*
* Date: 2023-12-21 13:32
* LastEditors: Fan Hao
* LastEditTime: 2023-12-21 13:32
* Revisions: Rev 0.0
* History:
* [2023-12-21]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Scheduler
* @{
*/
#ifndef SCHDEVENT_H_
#define SCHDEVENT_H_
@@ -24,8 +30,9 @@
#include "clist.h"
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/** @name L2 event
* A definition of L2 event instance.
/**
* @struct L2_SCHD_EVENT
* @brief Linklayer scheduled event descriptor
*/
typedef struct
{
@@ -38,8 +45,9 @@ typedef struct
uint32_t schdSlot;
} L2_SCHD_EVENT;
/** @name L2 event
* A definition of L2 event instance.
/**
* @struct L2_SCHD_POOL
* @brief Linklayer schedule event pool instance
*/
typedef struct
{
@@ -63,3 +71,6 @@ bool L2_isEventScheduled(const L2_SCHD_EVENT *schdEvent);
int32_t L2_CancelEvent(L2_SCHD_EVENT *schdEvent);
#endif // SCHDEVENT_H_
/** @} LinkLayer_Scheduler*/
/** @} LinkLayer*/
+149 -102
View File
@@ -1,18 +1,24 @@
/*****************************************************************************/
/**
* Description: Implementations for df datalink service net.
* Date: 2021-11-16 00:08
* LastEditTime: 2022-07-16 17:04
* Revisions: Rev 0.1
* History:
* [2022-07-16]: New branch for DiJian.
* [2021-11-16]: Initial version.
* @file service.c
* @author FanHao ([email protected])
* @brief DF Linklayer service implementation file.
* @version 0.0
* @date 2023-05-06
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_Service
* @{
*/
/***************************** Include Files *********************************/
#include <string.h>
#include <stdint.h>
@@ -88,6 +94,7 @@ static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
uint32_t dataChunk;
uint8_t *buff = instPtr->sendPktData;
// Common section of link layer package
dataChunk = L2_GetNextFrameNum(instPtr);
L2_FrameInsertChunk(buff, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &dataChunk);
dataChunk = L2_GetNextSlotNum(instPtr);
@@ -115,11 +122,11 @@ static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
uint32_t dataId;
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_GetSendPayloadRaw(buff + L2_MSG_SVC_PAYLOAD, &dataId, PAYLOAD_LEN_FLJ_TX);
SysMonitor_GetSendPayload(buff + L2_MSG_SVC_PAYLOAD, &dataId, PAYLOAD_LEN_FLJ_TX);
}
else
{
SysMonitor_GetSendPayloadRaw(buff + L2_MSG_SVC_PAYLOAD, &dataId, PAYLOAD_LEN_LJ_TX);
SysMonitor_GetSendPayload(buff + L2_MSG_SVC_PAYLOAD, &dataId, PAYLOAD_LEN_LJ_TX);
}
L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD_ID, L2_MSG_SVC_PAYLOAD_ID_LEN, &dataId);
@@ -128,19 +135,15 @@ static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD, L2_MSG_SVC_PAYLOAD_LEN, testData);
}
// // packing payload
// uint32_t dataId;
// dataId = DATA_ID_TEST;
// L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD_ID, L2_MSG_SVC_PAYLOAD_ID_LEN, &dataId);
// L2_FrameInsertChunk(buff, L2_MSG_SVC_PAYLOAD, L2_MSG_SVC_PAYLOAD_LEN, testData);
Status = L2_CrcAppend(buff, L2_SVC_PACK_LEN - L2_MSG_SVC_CRC_LEN, L2_MSG_SVC_CRC, L2_CRC16_1021);
if (Status != SUCCESS)
{
DBG_ERROR("Fail to append CRC...\n");
return Status;
}
memcpy(instPtr->log.txLog.data, buff, L2_SVC_PACK_LEN);
instPtr->log.txLog.dataId = dataId;
break;
}
default:
@@ -157,62 +160,6 @@ static int32_t Service_Packing(L2_INST *instPtr, L2_FRAME_TYPE type, uint8_t dst
#endif
}
/*****************************************************************************/
/**
* @brief Initialize service net FSM
*
* @param serviceFSM A pointer to service FSM instance.
*
* @return SUCCESS Initialize successfully.
* Other Initialize failed.
*
******************************************************************************/
int32_t L2_Service_Init(L2_SVC_FSM **svcFSMPtr)
{
ASSERT(svcFSMPtr != NULL);
*svcFSMPtr = (L2_SVC_FSM *)malloc(sizeof(L2_SVC_FSM));
if (*svcFSMPtr == NULL)
{
return ENOMEM;
}
L2_Service_Reset(*svcFSMPtr);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Reset ServiceNet FSM
*
* @param scanFsmPtr a pointer to service net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr)
{
ASSERT(svcFSMPtr != NULL);
memset((&svcFSMPtr->rxLog), 0x00, sizeof(PAYLOAD));
memset((&svcFSMPtr->txLog), 0x00, sizeof(PAYLOAD));
#ifdef DATALINK_ENABLE_BERTEST
svcFSMPtr->bitTotal = 0;
svcFSMPtr->bitError = 0;
#endif
}
/*****************************************************************************/
/**
* @brief Destroy ServiceNet FSM, free memory
*
* @param scanFsmPtr a pointer to service net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Service_Destroy(L2_SVC_FSM *serviceFSM)
{
free(serviceFSM);
}
/*****************************************************************************/
/**
* @brief Handle service received packet. Send data up to MPC
@@ -227,9 +174,9 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
{
ASSERT(instPtr != NULL);
ASSERT(msg != NULL);
#ifndef DATALINK_ENABLE_BERTEST
int32_t Status;
uint8_t frameType;
#ifndef DATALINK_ENABLE_BERTEST
L2_FRAME_TYPE frameType = L2_NONE_FRAME;
L2_FrameGetChunk(msg, L2_MSG_TYPE, L2_MSG_TYPE_LEN, &frameType);
switch (frameType)
{
@@ -269,29 +216,40 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
// Reset node ttl
node->ttlCnt = 0;
// Calculate time deviation
uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS)
{
DBG_ERROR("Failed to compute time deviation.\n")
break;
}
uint32_t dataId;
L2_FrameGetChunk(msg, L2_MSG_SVC_PAYLOAD_ID, L2_MSG_SVC_PAYLOAD_ID_LEN, &dataId);
if(dataId != DATA_ID_NONE)
{
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
SysMonitor_UpdateRecvPayloadRaw(msg+L2_MSG_SVC_PAYLOAD, PAYLOAD_LEN_FLJ_RX);
SysMonitor_UpdateRecvPayload(msg + L2_MSG_SVC_PAYLOAD, dataId, PAYLOAD_LEN_FLJ_RX);
}
else
{
SysMonitor_UpdateRecvPayloadRaw(msg+L2_MSG_SVC_PAYLOAD, PAYLOAD_LEN_LJ_RX);
}
SysMonitor_UpdateRecvPayload(msg + L2_MSG_SVC_PAYLOAD, dataId, PAYLOAD_LEN_LJ_RX);
}
// Logging
memcpy(instPtr->log.rxLog.data, msg, L2_SVC_PACK_LEN);
instPtr->log.rxLog.dataId = dataId;
instPtr->serviceFSM->rxdCnt++;
#ifdef DATALINK_ENABLE_AUTOTIMESYNC
// Implement a auto time sync.
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
uint32_t frameNum, slotNum;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
L2_TimeAlign(instPtr, frameNum, slotNum, true);
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
}
#endif
break;
@@ -303,25 +261,93 @@ int32_t L2_Service_PktHandler(L2_INST *instPtr, uint8_t *msg)
return Status;
#else
uint32_t errorBits = 0;
for (int i = 0; i < SVC_PACK_LEN; i++)
for (int i = 0; i < L2_SVC_PACK_LEN; i++)
{
errorBits += count_ones(msg[i] ^ testData[i]);
}
instPtr->serviceFsm.bitError += errorBits;
instPtr->serviceFsm.bitTotal += SVC_PACK_LEN * 8;
instPtr->serviceFSM->bitError += errorBits;
instPtr->serviceFSM->bitTotal += L2_SVC_PACK_LEN * 8;
// Calculate time deviation
uint32_t frameNum, slotNum = 0;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
Status = L2_GetTimeDeviation(instPtr, frameNum, slotNum, true, &(instPtr->log.timeDev));
if (Status != SUCCESS)
{
DBG_ERROR("Failed to compute time deviation.\n")
return Status;
}
// Implement a auto time sync.
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD)
{
uint32_t frameNum, slotNum;
L2_FrameGetChunk(msg, L2_MSG_FRAME_NUM, L2_MSG_FRAME_NUM_LEN, &frameNum);
L2_FrameGetChunk(msg, L2_MSG_SLOT_NUM, L2_MSG_SLOT_NUM_LEN, &slotNum);
L2_TimeAlign(instPtr, frameNum, slotNum, true);
// Time sync.
L2_TimeAdjust(instPtr, &(instPtr->log.timeDev));
}
return SUCCESS;
#endif
}
/*****************************************************************************/
/**
* @brief Initialize service net FSM
*
* @param serviceFSM A pointer to service FSM instance.
*
* @return SUCCESS Initialize successfully.
* Other Initialize failed.
*
******************************************************************************/
int32_t L2_Service_Init(L2_SVC_FSM **svcFSMPtr)
{
ASSERT(svcFSMPtr != NULL);
*svcFSMPtr = (L2_SVC_FSM *)malloc(sizeof(L2_SVC_FSM));
if (*svcFSMPtr == NULL)
{
return ENOMEM;
}
L2_Service_Reset(*svcFSMPtr);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Reset ServiceNet FSM
*
* @param scanFsmPtr a pointer to service net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Service_Reset(L2_SVC_FSM *svcFSMPtr)
{
ASSERT(svcFSMPtr != NULL);
svcFSMPtr->txCnt = 0;
svcFSMPtr->rxCnt = 0;
svcFSMPtr->rxdCnt = 0;
#ifdef DATALINK_ENABLE_BERTEST
svcFSMPtr->bitTotal = 0;
svcFSMPtr->bitError = 0;
svcFSMPtr->lossRate = 0;
svcFSMPtr->errorRate = 0;
#endif
}
/*****************************************************************************/
/**
* @brief Destroy ServiceNet FSM, free memory
*
* @param scanFsmPtr a pointer to service net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Service_Destroy(L2_SVC_FSM *serviceFSM)
{
free(serviceFSM);
}
/*****************************************************************************/
/**
* @brief Service FSM Routine.
@@ -343,35 +369,54 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
}
PHY_INST *phyRef = instPtr->config.phyInstPtr;
L2_SVC_FSM *svcFSMPtr = instPtr->serviceFSM;
L2_TOR_TYPE torState;
const NODE_ENTRY *commNode;
if (rtneEntry->src == L2_GetNodeId(instPtr))
{
torState = L2_TOR_TX;
commNode = L2_GetNodeById(instPtr->nodeList, rtneEntry->dst);
}
else if (rtneEntry->dst == L2_GetNodeId(instPtr))
{
torState = L2_TOR_RX;
commNode = L2_GetNodeById(instPtr->nodeList, rtneEntry->src);
}
else
{
torState = L2_TOR_SUSPEND;
}
// Setup antenna beam
if (L2_GetNodeType(instPtr) != L2_NODE_HEAD && commNode != NULL)
{
Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_16);
Phy_SetBeamNo(phyRef, commNode->nodeInfo.beamNo, PHY_ANT_BEAM_16);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_16;
}
else
{
Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_120);
instPtr->log.lastBeamWidth = PHY_ANT_BEAM_120;
}
switch (rtneEntry->slotType)
{
case L2_SLOT_SERVICE:
if (torState == L2_TOR_TX)
{
svcFSMPtr->txCnt++;
#ifndef DATALINK_ENABLE_BERTEST
// Packing service data
Service_Packing(instPtr, L2_SVC_FRAME, rtneEntry->dst);
#else
memcpy(instPtr->sendPktData, testData, SVC_PACK_LEN);
memcpy(instPtr->sendPktData, testData, L2_SVC_PACK_LEN);
#endif
}
// FIXME: Steer antenna to point to destination.
Phy_SetBeamAngle(phyRef, 0.0, 0.0);
Phy_SetBeamWidth(phyRef, PHY_ANT_BEAM_8);
else
{
svcFSMPtr->rxCnt++;
}
L2_SetupNextSlot(instPtr, torState, L2_SVC_FRAME);
break;
default:
@@ -380,12 +425,14 @@ int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntr
}
#ifdef DATALINK_ENABLE_BERTEST
uint32_t pktLoss;
double errorRate, lossRate;
pktLoss = instPtr->log.svcRecvCnt - instPtr->log.svcCorrectCnt;
lossRate = (instPtr->log.svcRecvCnt == 0) ? 0 : (double)pktLoss / (double)instPtr->serviceFsm.pktRecv;
errorRate = (instPtr->serviceFsm.bitTotal == 0) ? 0 : (double)instPtr->serviceFsm.bitError / (double)instPtr->serviceFsm.bitTotal;
DBG_PRINT("Packet Loss Rate -- Total: %lu, Loss: %lu.\n", instPtr->serviceFsm.pktRecv, pktLoss);
DBG_PRINT("Bit Error Rate -- Total:%lu, Error:%lu.\n", instPtr->serviceFsm.bitTotal, instPtr->serviceFsm.bitError);
pktLoss = svcFSMPtr->rxCnt - svcFSMPtr->rxdCnt;
svcFSMPtr->lossRate = (svcFSMPtr->rxCnt == 0) ? 0 : (double)pktLoss / (double)svcFSMPtr->rxCnt;
svcFSMPtr->errorRate = (svcFSMPtr->bitTotal == 0) ? 0 : (double)svcFSMPtr->bitError / (double)svcFSMPtr->bitTotal;
DBG_PRINT("Packet Loss Rate -- Total: %lu, Loss: %lu.\n", instPtr->log.svcRxCnt, pktLoss);
DBG_PRINT("Bit Error Rate -- Total:%lu, Error:%lu.\n", svcFSMPtr->bitTotal, svcFSMPtr->bitError);
#endif
return SUCCESS;
}
/** @} LinkLayer_Service*/
/** @} LinkLayer*/
@@ -1,21 +1,24 @@
/*****************************************************************************/
/**
* Description: Time sync implementation file.
* @file time_sync.c
* @author FanHao ([email protected])
* @brief DF Linklayer time sync implementation file.
* @version 0.0
* @date 2023-05-06
*
* Author: Author's name
* Date: 2021-12-04 16:32
* LastEditors: FanHao
* LastEditTime: 2022-07-10 20:43
* Revisions: Rev 0.0
* History:
* [2022-07-10]: New branch for Dijian.
* [2021-12-04]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup LinkLayer
* @{
*/
/**
* @addtogroup LinkLayer_TimeSync
* @{
*/
/***************************** Include Files *********************************/
#include <string.h>
#include <stdlib.h>
@@ -32,22 +35,25 @@
/*****************************************************************************/
/**
* @brief a slot alignment, base on physical layer information.
* @brief Get time deviation to the specified frame and slot number.
*
* @param instPtr a pointer to linklayer layer instance
* @param frameNum
* @param slotNum
* @param relative
* @param timeDev
*
* @return SUCCESS Initialize successfully.
* FAILURE Initialization failed, allocate memory fail or initial
* bram controller fail.
* @return SUCCESS
* EIGNORE there is no received frame
*
******************************************************************************/
// TODO: Check
int32_t L2_TimeAlign(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool relative)
int32_t L2_GetTimeDeviation(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool relative, int64_t *timeDev)
{
ASSERT(instPtr != NULL);
ASSERT(timeDev != NULL);
L1_FRAME_TYPE lastRecvdFrame;
lastRecvdFrame = Phy_GetLastRecvFrameType(instPtr->config.phyInstPtr);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
lastRecvdFrame = Phy_GetLastRecvFrameType(phyRef);
if (lastRecvdFrame == L1_NONE_FRAME)
{
DBG_ERROR("Invalid TimeAlign operation, no frame was received.");
@@ -57,8 +63,7 @@ int32_t L2_TimeAlign(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool
DBG_INFO("Starting TimeAlign operation...\n");
// read nextSendTime from physical layer
uint64_t currTime, expectTime;
int64_t timeDiff;
TIME_WORD timeStamp, slotTimerAdjmet;
TIME_WORD timeStamp;
expectTime = ((uint64_t)(frameNum * L2_SLOTS_PER_FRAME + slotNum)) * TIME_FRAC_MAX;
expectTime += Phy_GetTimeComp(lastRecvdFrame);
@@ -67,14 +72,34 @@ int32_t L2_TimeAlign(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool
expectTime += (uint64_t)instPtr->netStartTime * L2_SLOTS_PER_FRAME * TIME_FRAC_MAX;
}
Phy_GetLastReceivedFrameSyncTimeStamp(instPtr->config.phyInstPtr, &timeStamp);
Phy_GetLastReceivedFrameSyncTimeStamp(phyRef, &timeStamp);
currTime = (uint64_t)timeStamp.frac_part;
currTime += ((uint64_t)timeStamp.int_part) * TIME_FRAC_MAX;
timeDiff = (int64_t)(expectTime - currTime);
slotTimerAdjmet.int_part = (uint32_t)(timeDiff / TIME_FRAC_MAX);
slotTimerAdjmet.frac_part = (uint32_t)(timeDiff % TIME_FRAC_MAX);
TimeCtrl_TimeAdjust(instPtr->config.tmcInstPtr, &slotTimerAdjmet, TM_ADJ_ADD);
*timeDev = (int64_t)(expectTime - currTime);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Implement time adjustment by applying time deviation.
*
* @param instPtr a pointer to linklayer layer instance
* @param timeDev
*
* @return NONE
*
******************************************************************************/
void L2_TimeAdjust(L2_INST *instPtr, const int64_t *timeDev)
{
ASSERT(instPtr != NULL);
ASSERT(timeDev != NULL);
TIME_WORD slotTimerAdjmet;
slotTimerAdjmet.int_part = (uint32_t)(*timeDev / TIME_FRAC_MAX);
slotTimerAdjmet.frac_part = (uint32_t)(*timeDev % TIME_FRAC_MAX);
TimeCtrl_TimeAdjust(instPtr->config.tmcInstPtr, &slotTimerAdjmet, TM_ADJ_ADD);
}
/** @} LinkLayer_TimeSync*/
/** @} LinkLayer*/
@@ -1,26 +1,36 @@
/*****************************************************************************/
/**
* Description: Antenna configuration functions.
* @file phy_antenna.h
* @author FanHao ([email protected])
* @brief Physical layer control antenna configuration functions.
* @version 0.0
* @date 2023-04-24
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:15
* Revisions: Rev 0.0
* History:
* [2024-01-20]: New branch for duifei.
* [2022-06-18]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup PhysicalLayer
* @{
*/
/**
* @addtogroup PhysicalLayer_AntennaControl
* @{
*/
#include <string.h>
#include <stdint.h>
#include <math.h>
#include "error.h"
#include "phy_layer.h"
/**
* @name PhysicalLayer_AntennaConfig_Constants
* @{
*/
#define ANT_PI 3.14159265358979323846
#define ANT_COINFO_HEAD 0xAA
@@ -29,16 +39,19 @@
#define CTRL_WORD_DEFAULT 0x00
#define ANT_MODE_BEAM_MASK 0xF0
#define ANT_MODE_NARROR_BEAM 0x00 // 8
#define ANT_MODE_WIDE_BEAM_1 0x10 // 25
#define ANT_MODE_WIDE_BEAM_2 0x20 // 60
#define ANT_MODE_WIDE_BEAM_3 0x30 // 120
#define ANT_BEAM_NARROR 0x00 // 8
#define ANT_BEAM_SUBNARROR_0 0x10 // 25
#define ANT_BEAM_SUBNARROR_1 0x20 // 60
#define ANT_BEAM_WIDE 0x30 // 120
#define ANT_MODE_HIGH_POWER 0x00
#define ANT_MODE_LOW_POWER 0x04
#define ANT_MODE_STANDBY 0x0F
#define ATN_MODE_DEFAULT (ANT_MODE_WIDE_BEAM_1 | ANT_MODE_LOW_POWER)
#define ATN_MODE_HIGH (ANT_MODE_WIDE_BEAM_1 | ANT_MODE_HIGH_POWER)
#define ANT_MODE_POWER_MASK 0x0F
#define ANT_POWER_FULL 0x00
#define ANT_POWER_LOW 0x04
#define ANT_POWER_STANDBY 0x0F
#define ATN_MODE_SILENT (ANT_BEAM_SUBNARROR_0 | ANT_POWER_STANDBY)
#define ATN_MODE_LOWPOWER (ANT_BEAM_SUBNARROR_0 | ANT_POWER_LOW)
#define ATN_MODE_FULLPOWER (ANT_BEAM_SUBNARROR_0 | ANT_POWER_FULL)
#define ATN_MODE_DEFAULT ATN_MODE_SILENT
#define DEFAULT_CENTRTAL_FREQ 0x06D7 // 26.25GHz
@@ -54,141 +67,134 @@
// Pair by regex
// Regex: (([0-9]+, ){8})
uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS] =
const uint16_t freqTable[L1_FRAME_MAX_HOPS] =
{
1084U, 1097U, 1110U, 1123U, 1136U, 1149U, 1162U, 1175U,
1188U, 1201U, 1214U, 1227U, 1240U, 1253U, 1266U, 1279U,
1292U, 1305U, 1318U, 1331U, 1344U, 1357U, 1370U, 1383U,
1396U, 1409U, 1422U, 1435U, 1448U, 1461U, 1474U, 1487U,
1500U, 1513U, 1526U, 1539U, 1552U, 1565U, 1578U, 1591U,
1604U, 1617U, 1630U, 1643U, 1656U, 1669U, 1682U, 1695U,
1708U, 1721U, 1734U, 1747U, 1760U, 1773U, 1786U, 1799U,
1812U, 1825U, 1838U, 1851U, 1864U, 1877U, 1890U, 1903U,
1916U, 1929U, 1942U, 1955U, 1968U, 1981U, 1994U, 2007U,
2020U, 2033U, 2046U, 2059U, 2072U, 2085U, 2098U, 2111U,
2124U
};
const int16_t antCalTable[L1_FRAME_MAX_HOPS][L1_ANT_NUM_CH] =
//Antenna-JG01
{
{ 0, 2525, -7533, -6846}, { 0, 12726, -7818, -6860},
{ 0, 2490, -7836, -6907}, { 0, 4479, -7716, -6837},
{ 0, 6409, -7770, -6776}, { 0, 14616, -7977, -6816},
{ 0, -22557, -8002, -6911}, { 0, -22587, -8121, -6918},
{ 0, -1124, -8123, -7030}, { 0, -152, -8219, -7042},
{ 0, 1823, -8209, -7130}, { 0, 1790, -8290, -7214},
{ 0, 1669, -8362, -7283}, { 0, 1634, -8459, -7276},
{ 0, 1615, -8315, -7415}, { 0, 1698, -8168, -7366},
{ 0, 1535, -8285, -7520}, { 0, 1619, -8285, -7532},
{ 0, 1609, -8201, -7693}, { 0, 1671, -8145, -7769},
{ 0, 1676, -8135, -7805}, { 0, 951, -10279, -8871},
{ 0, 976, -10235, -8978}, { 0, 1118, -10127, -9019},
{ 0, 1175, -10003, -9007}, { 0, 1386, -9847, -9039},
{ 0, 1535, -9572, -9058}, { 0, 1729, -9493, -9006},
{ 0, -1158, -9312, -9003}, { 0, 23771, -9147, -8928},
{ 0, 20733, -9074, -8924}, { 0, 2455, -8841, -8886},
{ 0, 2622, -8718, -8735}, { 0, 2791, -8615, -8705},
{ 0, 2861, -8168, -8331}, { 0, 3076, -8091, -8218},
{ 0, 3257, -8046, -8100}, { 0, 3331, -7923, -8073},
{ 0, 3396, -7826, -7994}, { 0, 3478, -7842, -8016},
{ 0, 3518, -7846, -7765}, { 0, 3585, -7753, -7715},
{ 0, 150, -8145, -8591}, { 0, 192, -8090, -8570},
{ 0, 207, -8150, -8597}, { 0, 178, -8142, -8656},
{ 0, 89, -8557, -8688}, { 0, 107, -8614, -8733},
{ 0, 194, -8605, -8782}, { 0, 153, -8655, -8881},
{ 0, 70, -8615, -8952}, { 0, 35, -8596, -9148},
{ 0, 49, -8636, -9286}, { 0, 6, -8587, -9435},
{ 0, -51, -8540, -9549}, { 0, -65, -8588, -9700},
{ 0, -55, -8503, -9820}, { 0, -20, -8414, -9907},
{ 0, -112, -8481, -10031}, { 0, -69, -8535, -10185},
{ 0, 2, -8550, -10052}, { 0, -1, -8493, -10291},
{ 0, -73, -8441, -10380}, { 0, 1958, -6930, -8295},
{ 0, -1148, -6939, -8396}, { 0, 1915, -6784, -8370},
{ 0, 1871, -6970, -8514}, { 0, 1821, -6974, -8387},
{ 0, 1781, -6906, -8431}, { 0, 1736, -6897, -8462},
{ 0, 1664, -7024, -8377}, { 0, 1629, -7127, -8436},
{ 0, 1603, -7148, -8528}, { 0, 1577, -7198, -8500},
{ 0, 1528, -7311, -8512}, { 0, 1577, -7390, -8570},
{ 0, 1616, -7436, -8572}, { 0, 1589, -7597, -8590},
{ 0, 1722, -7550, -8568}, { 0, 1741, -7691, -8449},
{ 0, 1767, -7775, -8328},
};
const uint8_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] =
{
0
};
uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] =
const uint8_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] =
{
1500
0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U,
16U, 17U, 18U, 19U, 20U, 21U, 22U, 23U,
24U, 25U, 26U, 27U, 28U, 29U, 30U, 31U,
32U, 33U, 34U, 35U, 36U, 37U, 38U, 39U,
40U, 41U, 42U, 43U, 44U, 45U, 46U, 47U,
48U, 49U, 50U, 51U, 52U, 53U, 54U, 55U,
56U, 57U, 58U, 59U, 60U, 61U, 62U, 63U,
64U, 65U, 66U, 67U, 68U, 69U, 70U, 71U,
72U, 73U, 74U, 75U, 76U, 77U, 78U, 79U,
80U
};
uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] =
const uint8_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] =
{
0, 44, 88, 131, 175, 219, 263, 306,
350, 394, 438, 481, 525, 569, 613, 656,
700, 744, 788, 831, 875, 919, 963, 1006,
1050, 1094, 1138, 1181, 1225, 1269, 1313, 1356,
1400, 1444, 1488, 1531, 1575, 1619, 1663, 1706,
1750, 1794, 1838, 1881, 1925, 1969, 2013, 2056,
2100, 2144, 2188, 2231, 2275, 2319, 2363, 2406,
2450, 2494, 2538, 2581, 2625, 2669, 2713, 2756,
2800, 2844, 2888, 2931, 2975, 3019, 3063, 3106,
3150, 3194, 3238, 3281, 3325, 3369, 3413, 3456,
3500
80U
};
uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] =
const uint8_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] =
{
1500
80U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
8U, 9U, 10U
};
uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] =
const uint8_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS] =
{
1500
0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
8U,
};
uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS] =
const uint8_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] =
{
1600
0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U,
16U, 17U, 18U
};
uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] =
const uint8_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS] =
{
1600
0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U,
16U, 17U, 18U, 19U
};
uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS] =
const uint8_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS] =
{
500, 1600, 1700, 1800, 1900, 2000, 1500, 1600,
1700, 1800, 1900, 2000, 1500, 1600, 1700, 1800,
1900, 2000, 1500, 1500
0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U,
16U, 17U, 18U, 19U
};
uint16_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS] =
{
500, 600, 700, 800, 900, 1000, 500, 600,
700, 800, 900, 1000, 500, 600, 700, 800,
900, 1000, 500, 500
};
/** @} PhysicalLayer_AntennaConfig_Constants*/
// Pair by regex
// Regex: ((\{\.oaxis = [0-9]+[ ,]+\.raxis = [0-9]+[ ]*\}, ){2})
#ifdef PHY_BEAM_SET_PRESET
PHY_ANT_ANGLE antSubnrrwPattern[L1_NUM_ANT_SUBNRRW_PATTERN] =
{
{.oaxis = 0 , .raxis = 222}, {.oaxis = 10, .raxis = 85 },
{.oaxis = 14, .raxis = 307}, {.oaxis = 17, .raxis = 170},
{.oaxis = 19, .raxis = 32 }, {.oaxis = 21, .raxis = 255},
{.oaxis = 24, .raxis = 117}, {.oaxis = 25, .raxis = 340},
{.oaxis = 27, .raxis = 202}, {.oaxis = 29, .raxis = 65 },
{.oaxis = 31, .raxis = 287}, {.oaxis = 32, .raxis = 150},
{.oaxis = 34, .raxis = 12 }, {.oaxis = 35, .raxis = 235},
{.oaxis = 36, .raxis = 97 }, {.oaxis = 38, .raxis = 320},
{.oaxis = 39, .raxis = 182}, {.oaxis = 40, .raxis = 45 },
{.oaxis = 41, .raxis = 267}, {.oaxis = 43, .raxis = 130},
{.oaxis = 44, .raxis = 352}, {.oaxis = 45, .raxis = 215},
{.oaxis = 46, .raxis = 77 }, {.oaxis = 47, .raxis = 300},
{.oaxis = 48, .raxis = 162}, {.oaxis = 49, .raxis = 25 },
{.oaxis = 50, .raxis = 247}, {.oaxis = 51, .raxis = 110},
{.oaxis = 52, .raxis = 332}, {.oaxis = 53, .raxis = 195},
{.oaxis = 54, .raxis = 57 }, {.oaxis = 55, .raxis = 280},
{.oaxis = 56, .raxis = 142}, {.oaxis = 57, .raxis = 5 },
{.oaxis = 58, .raxis = 227}, {.oaxis = 59, .raxis = 90 },
{.oaxis = 60, .raxis = 312}
};
PHY_ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN] =
{
{.oaxis = 0 , .raxis = 222}, {.oaxis = 7 , .raxis = 85 },
{.oaxis = 10, .raxis = 307}, {.oaxis = 13, .raxis = 170},
{.oaxis = 15, .raxis = 32 }, {.oaxis = 17, .raxis = 255},
{.oaxis = 18, .raxis = 117}, {.oaxis = 20, .raxis = 340},
{.oaxis = 21, .raxis = 202}, {.oaxis = 22, .raxis = 65 },
{.oaxis = 24, .raxis = 287}, {.oaxis = 25, .raxis = 150},
{.oaxis = 26, .raxis = 12 }, {.oaxis = 27, .raxis = 235},
{.oaxis = 28, .raxis = 97 }, {.oaxis = 29, .raxis = 320},
{.oaxis = 30, .raxis = 182}, {.oaxis = 31, .raxis = 45 },
{.oaxis = 32, .raxis = 267}, {.oaxis = 33, .raxis = 130},
{.oaxis = 34, .raxis = 352}, {.oaxis = 34, .raxis = 215},
{.oaxis = 35, .raxis = 77 }, {.oaxis = 36, .raxis = 300},
{.oaxis = 37, .raxis = 162}, {.oaxis = 38, .raxis = 25 },
{.oaxis = 38, .raxis = 247}, {.oaxis = 39, .raxis = 110},
{.oaxis = 40, .raxis = 332}, {.oaxis = 41, .raxis = 195},
{.oaxis = 41, .raxis = 57 }, {.oaxis = 42, .raxis = 280},
{.oaxis = 43, .raxis = 142}, {.oaxis = 44, .raxis = 5 },
{.oaxis = 44, .raxis = 227}, {.oaxis = 45, .raxis = 90 },
{.oaxis = 46, .raxis = 312}, {.oaxis = 46, .raxis = 175},
{.oaxis = 47, .raxis = 37 }, {.oaxis = 48, .raxis = 260},
{.oaxis = 48, .raxis = 122}, {.oaxis = 49, .raxis = 345},
{.oaxis = 49, .raxis = 207}, {.oaxis = 50, .raxis = 70 },
{.oaxis = 51, .raxis = 292}, {.oaxis = 51, .raxis = 155},
{.oaxis = 52, .raxis = 17 }, {.oaxis = 53, .raxis = 240},
{.oaxis = 53, .raxis = 102}, {.oaxis = 54, .raxis = 325},
{.oaxis = 54, .raxis = 187}, {.oaxis = 55, .raxis = 50 },
{.oaxis = 55, .raxis = 272}, {.oaxis = 56, .raxis = 135},
{.oaxis = 57, .raxis = 357}, {.oaxis = 57, .raxis = 220},
{.oaxis = 58, .raxis = 82 }, {.oaxis = 58, .raxis = 305},
{.oaxis = 59, .raxis = 167}, {.oaxis = 59, .raxis = 30 },
{.oaxis = 60, .raxis = 252}
};
#else
PHY_ANT_ANGLE antSubnrrwPattern[L1_NUM_ANT_SUBNRRW_PATTERN] =
{
0
};
PHY_ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN] =
{
0
};
#endif
/*****************************************************************************/
/**
* @brief
* @brief Initialize antenna configurations (load preset values)
*
* @param antConfig
* @param antConfig pointer to antenna configure
*
* @return
* @return None.
*
******************************************************************************/
void Phy_AntConfigInit(PHY_ANT_CONFIG *antConfig)
@@ -214,7 +220,7 @@ void Phy_AntConfigInit(PHY_ANT_CONFIG *antConfig)
// trSelect
antConfig->trSlect = 0;
// Antenna attenuation setting
antConfig->antAtt = 20;
antConfig->antAtt = 0;
// phase setting
antConfig->phase = 0;
// ***********************
@@ -242,32 +248,80 @@ void Phy_AntConfigInit(PHY_ANT_CONFIG *antConfig)
// ***********************
}
/*****************************************************************************/
/**
* @brief Update antenna power mode setting
*
* @param instPtr pointer to physical layer instance
* @param mode new antenna mode
*
* @return None.
*
******************************************************************************/
void Phy_AntConfigMode(PHY_INST *instPtr, PHY_ANT_MODE mode)
{
ASSERT(instPtr != NULL);
uint8_t config = instPtr->antConfig.antMode & ANT_MODE_BEAM_MASK;
switch (mode)
{
case PHY_ANT_MODE_SILENT:
config |= ANT_MODE_STANDBY;
case PHY_ANT_MODE_STANDBY:
config |= ANT_POWER_STANDBY;
break;
case PHY_ANT_MODE_LOW_POWER:
config |= ANT_MODE_LOW_POWER;
case PHY_ANT_MODE_POWER_LOW:
config |= ANT_POWER_LOW;
break;
case PHY_ANT_MODE_HIGH_POWER:
config |= ANT_MODE_HIGH_POWER;
case PHY_ANT_MODE_POWER_FULL:
config |= ANT_POWER_FULL;
break;
default:
DBG_ERROR("Unknown antenna mode: %" PRIu8 ", remain previous mode.\n", mode);
return;
}
instPtr->phyLog.antMode = mode;
instPtr->antConfig.antMode = config;
// Sync logs to system monitor
SysMonitor_UpdatePhysicalLayerLog(&(instPtr->phyLog));
}
int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo)
/*****************************************************************************/
/**
* @brief Update antenna beam table
*
* @param instPtr pointer to physical layer instance
* @param table new beam table
* @param offset table offset
*
* @return None
*
******************************************************************************/
void Phy_SetBeamTable(PHY_INST *instPtr, PHY_ANT_ANGLE *table, uint32_t offset)
{
ASSERT(instPtr != NULL);
if (instPtr->beamWd.next == PHY_ANT_BEAM_8)
ASSERT(table != NULL);
for (int i = 0; i < L1_NUM_ANT_NRRW_PATTERN; i++)
{
instPtr->antNrrwPattern[i] = table[(i + offset) % L1_NUM_ANT_NRRW_PATTERN];
}
memcpy((uint32_t *)instPtr->antInfoAddr, instPtr->antNrrwPattern,
L1_NUM_ANT_NRRW_PATTERN * sizeof(PHY_ANT_ANGLE));
}
/*****************************************************************************/
/**
* @brief Update antenna point direction using predefined beam table
*
* @param instPtr pointer to physical layer instance
* @param beamNo new beam index
*
* @return SUCCESS.
* FAILURE beamNo exceeds the table size
*
******************************************************************************/
int32_t Phy_SetBeamNo(PHY_INST *instPtr, size_t beamNo, PHY_ANT_BEAM_WIDTH beamWidth)
{
ASSERT(instPtr != NULL);
if (beamWidth == PHY_ANT_BEAM_16)
{
if (beamNo >= L1_NUM_ANT_NRRW_PATTERN)
{
@@ -276,26 +330,10 @@ int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo)
else
{
instPtr->beamNo.next = beamNo;
instPtr->antConfig.oaxis[1] = (uint8_t)(antNrrwPattern[beamNo].oaxis);
instPtr->antConfig.oaxis[0] = (uint8_t)((antNrrwPattern[beamNo].oaxis) >> 8);
instPtr->antConfig.raxis[1] = (uint8_t)(antNrrwPattern[beamNo].raxis);
instPtr->antConfig.raxis[0] = (uint8_t)((antNrrwPattern[beamNo].raxis) >> 8);
return SUCCESS;
}
}
else if (instPtr->beamWd.next == PHY_ANT_BEAM_25)
{
if (beamNo >= L1_NUM_ANT_SUBNRRW_PATTERN)
{
return FAILURE;
}
else
{
instPtr->beamNo.next = beamNo;
instPtr->antConfig.oaxis[1] = (uint8_t)(antSubnrrwPattern[beamNo].oaxis);
instPtr->antConfig.oaxis[0] = (uint8_t)((antSubnrrwPattern[beamNo].oaxis) >> 8);
instPtr->antConfig.raxis[1] = (uint8_t)(antSubnrrwPattern[beamNo].raxis);
instPtr->antConfig.raxis[0] = (uint8_t)((antSubnrrwPattern[beamNo].raxis) >> 8);
instPtr->antConfig.oaxis[0] = (uint8_t)(instPtr->antNrrwPattern[beamNo].oaxis >> 8);
instPtr->antConfig.oaxis[1] = (uint8_t)(instPtr->antNrrwPattern[beamNo].oaxis);
instPtr->antConfig.raxis[0] = (uint8_t)(instPtr->antNrrwPattern[beamNo].raxis >> 8);
instPtr->antConfig.raxis[1] = (uint8_t)(instPtr->antNrrwPattern[beamNo].raxis);
return SUCCESS;
}
}
@@ -304,15 +342,26 @@ int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo)
// Beam number assign not support.
// Assign default angle (0,0)
instPtr->beamNo.next = 0;
instPtr->antConfig.oaxis[1] = 0;
instPtr->antConfig.oaxis[0] = 0;
instPtr->antConfig.raxis[1] = 0;
instPtr->antConfig.oaxis[1] = 0;
instPtr->antConfig.raxis[0] = 0;
instPtr->antConfig.raxis[1] = 0;
DBG_WARNING("Using default beam number...\n");
return SUCCESS;
}
}
/*****************************************************************************/
/**
* @brief Update antenna beam width setting
*
* @param instPtr pointer to physical layer instance
* @param beamWidth new beam width
*
* @return SUCCESS.
* EPARAM
*
******************************************************************************/
int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth)
{
ASSERT(instPtr != NULL);
@@ -320,35 +369,45 @@ int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth)
switch (beamWidth)
{
case PHY_ANT_BEAM_120:
beamConfig |= ANT_MODE_WIDE_BEAM_3;
beamConfig |= ANT_BEAM_WIDE;
break;
case PHY_ANT_BEAM_60:
beamConfig |= ANT_MODE_WIDE_BEAM_2;
beamConfig |= ANT_BEAM_SUBNARROR_1;
break;
case PHY_ANT_BEAM_25:
beamConfig |= ANT_MODE_WIDE_BEAM_1;
beamConfig |= ANT_BEAM_SUBNARROR_0;
break;
case PHY_ANT_BEAM_8:
beamConfig |= ANT_MODE_NARROR_BEAM;
case PHY_ANT_BEAM_16:
beamConfig |= ANT_BEAM_NARROR;
break;
default:
DBG_ERROR("Beam width code: 0x%08X is illegal.\n\r", beamWidth);
return EPARAM;
break;
}
instPtr->antConfig.antMode = beamConfig;
instPtr->beamWd.next = beamWidth;
return SUCCESS;
}
// Common version radius double input
/*****************************************************************************/
/**
* @brief Set antenna to a specific direction
*
* @param instPtr pointer to physical layer instance
* @param offAx elevation angle
* @param rndAx azimuth angle
*
* @return SUCCESS.
* EPARAM - the direction is exceeds predefined range
*
******************************************************************************/
int32_t Phy_SetBeamAngle(PHY_INST *instPtr, double offAx, double rndAx)
{
ASSERT(instPtr != NULL);
uint16_t offAxDeg = 0;
uint16_t rndAxDeg = 0;
offAxDeg = (offAx >= 0) ? (((int32_t)(offAx * 180 / ANT_PI)) % 360) : (((int32_t)(offAx * 180 / ANT_PI)) % 360 + 360);
rndAxDeg = (rndAx >= 0) ? (((int32_t)(rndAx * 180 / ANT_PI)) % 360) : (((int32_t)(rndAx * 180 / ANT_PI)) % 360 + 360);
offAxDeg = (offAx >= 0) ? (((int32_t)(offAx * 180.0 / ANT_PI)) % 360) : (((int32_t)(offAx * 180.0 / ANT_PI)) % 360 + 360);
rndAxDeg = (rndAx >= 0) ? (((int32_t)(rndAx * 180.0 / ANT_PI)) % 360) : (((int32_t)(rndAx * 180.0 / ANT_PI)) % 360 + 360);
if (offAxDeg > 60)
{
DBG_ERROR("Angle out of range, off axis angle: %" PRIu16 " (should be 0~60), round axis angle: %" PRIu16 " (should be 0~360).\n",
@@ -357,9 +416,13 @@ int32_t Phy_SetBeamAngle(PHY_INST *instPtr, double offAx, double rndAx)
}
offAxDeg = offAxDeg * 10;
rndAxDeg = rndAxDeg * 10;
instPtr->antConfig.oaxis[1] = (uint8_t)offAxDeg;
instPtr->antConfig.oaxis[0] = (uint8_t)(offAxDeg >> 8);
instPtr->antConfig.raxis[1] = (uint8_t)rndAxDeg;
instPtr->antConfig.oaxis[1] = (uint8_t)offAxDeg;
instPtr->antConfig.raxis[0] = (uint8_t)(rndAxDeg >> 8);
instPtr->antConfig.raxis[1] = (uint8_t)rndAxDeg;
return SUCCESS;
}
/** @} PhysicalLayer_AntennaControl*/
/** @} PhysicalLayer*/
File diff suppressed because it is too large Load Diff
@@ -1,63 +1,63 @@
/*****************************************************************************/
/**
* Description: Physical layer control definitions and function prototypes.
* @file phy_layer.c
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Physical layer control header file.
* @version 0.0
* @date 2023-04-24
*
* Date: 2021-12-04 16:32
* LastEditTime: 2024-01-20 17:41
* Revisions: Rev 0.1
* History:
* [2021-12-08]: Initial version.
* [2022-06-18]: New branch for glink control purpose:
* -Add poll mode, physical layer will start Tx/Rx procedure
* at specific time stamp.
* -Add 61/37 beam switch
* -Code simplification.
* [2023-04-24]: Feature add:
* - Read frame type from PL status register.
* [2024-01-20]: New branch for DUIFEI.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @defgroup PhysicalLayer
* @{
*/
#ifndef PHY_CTRL_H_
#define PHY_CTRL_H_
/***************************** Include Files *********************************/
#include <stdint.h>
#include "phy_reg.h"
#include "common.h"
#ifndef EMULATION
#include "xbram.h"
#include "xadcps.h"
#include "../config/app_config.h"
#endif
#include "../../system_monitor.h"
#include "../../time_ctrl/time_ctrl.h"
/************************** Constant Definitions *****************************/
#define L1_NUM_ANT_SUBNRRW_PATTERN 37
#define L1_NUM_ANT_NRRW_PATTERN 61
#define L1_INIT_BEAM_NO 0
/**
* @name PhysicalLayer_Common_Constant
* @{
*/
#define L1_NUM_ANT_NRRW_PATTERN 37U
#define L1_INIT_BEAM_NO 0U
#define L1_INIT_ANT_WD PHY_ANT_BEAM_120
#define L1_INIT_ANT_NO 0
#define L1_ANT_NUM_CH 4U
#define L1_FRAME_NONE_LEN UINT32_MAX // byte
#define L1_FRAME_NONE_COMP UINT32_MAX // *10ns(Timer_L)
#define L1_FRAME_NONE_HOPS UINT32_MAX
#define L1_FRAME_MAX_HOPS 81
#define L1_FRAME_2KBPS_20MS_HOPS 1
#define L1_FRAME_2KBPS_100MS_HOPS 81
#define L1_FRAME_10KBPS_10MS_HOPS 1
#define L1_FRAME_10KBPS_20MS_HOPS 11
#define L1_FRAME_40KBPS_20MS_HOPS 19
#define L1_FRAME_40KBPS_10MS_HOPS 9
#define L1_FRAME_200KBPS_5MS_HOPS 20
#define L1_FRAME_1M2BPS_5MS_HOPS 20
#define PHY_TIME_WORD_H_MAX UINT32_MAX
#define PHY_TIME_WORD_L_MAX 0x0007A120 // 5ms/10ns
#define L1_FRAME_MAX_HOPS 81U
#define L1_FRAME_2KBPS_20MS_HOPS 1U
#define L1_FRAME_2KBPS_100MS_HOPS 81U
#define L1_FRAME_10KBPS_10MS_HOPS 1U
#define L1_FRAME_10KBPS_20MS_HOPS 11U
#define L1_FRAME_40KBPS_20MS_HOPS 19U
#define L1_FRAME_40KBPS_10MS_HOPS 9U
#define L1_FRAME_200KBPS_5MS_HOPS 20U
#define L1_FRAME_1M2BPS_5MS_HOPS 20U
#define PHY_LOG_EXPIRE 40U // 50*5ms
/** @} */
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/**
* @enum L1_FRAME_TYPE
*/
typedef enum
{
L1_NONE_FRAME = 0,
@@ -71,71 +71,67 @@ typedef enum
L1_1M2BPS_5MS_FRAME = 8
} L1_FRAME_TYPE;
/**
* @struct PHY_ANT_CONFIG
* @brief PhysicalLayer antenna config
*/
typedef struct
{
/*** Ant Control ***/
/* Antenna control frame head 0xAA */
/* default 0, reserved for further use */
uint8_t ctrlWord;
/* high 4 bits specified beam mode.
* low 4 bits specified power control */
uint8_t antMode;
/* off-axis angle range is 0~60,
* 0.1 degree each LSB */
uint8_t oaxis[2];
/* round-axis angle range is 0~360,
* 0.1 degree each LSB */
uint8_t raxis[2];
/* 0~3500Mhz, step 1MHz */
uint8_t antFreq[2];
/* in single tr mode, 0~63 specified tr channel
* in single subarray mode, 0~3 specified the subarray
* Only in debug mode*/
uint8_t trSlect;
/* Antenna attenuation 0~31, 0.5dB each LSB, Only in debug mode */
uint8_t antAtt;
/* 0~63, 5.625 degree each LSB, Only in debug mode*/
uint8_t phase;
/* Only for debug */
/* default 0x00 */
uint8_t rxtxMode;
/* 0x00 Normal, 0x01 single tr calibration */
uint8_t calibrMode;
/* reserved for further use */
uint8_t antReserved;
uint8_t ctrlWord; ///< Antenna control frame head 0xAA\n
/// default 0, reserved for further use
uint8_t antMode; ///< high 4 bits specified beam mode.\n
/// low 4 bits specified power control
uint8_t oaxis[2]; ///< off-axis angle range is 0~60 \n
/// 0.1 degree each LSB
uint8_t raxis[2]; ///< round-axis angle range is 0~360, \n
/// 0.1 degree each LSB
uint8_t antFreq[2]; ///< 0~3500Mhz, step 1MHz
uint8_t trSlect; ///< in single tr mode, 0~63 specified tr channel \n
/// in single subarray mode, 0~3 specified the subarray
/// ! Only in debug mode!
uint8_t antAtt; ///< Antenna attenuation 0~31, 0.5dB each LSB, Only in debug mode
uint8_t phase; ///< 0~63, 5.625 degree each LSB, Only in debug mode
uint8_t rxtxMode; ///< Only for debug \n
/// default 0x00
uint8_t calibrMode; ///< 0x00 Normal, 0x01 single tr calibration
uint8_t antReserved; ///< reserved for further use
/*** RF Control ***/
/* [7:4]RF enable: 0-On, 1-Off(Default); [3:0]Work mode: 0(default) */
uint8_t rfCtrl;
/* 0~3500Mhz, step 1MHz */
uint8_t rfFreq[2];
/* RF MGC control: 0~31, 1dB each LSB*/
uint8_t rfTxMgc;
/* RF channel 1&2 calibration mgc: [7:4] Channle1 - max 15db, 1dB each LSB
* [3:0] Channle2 - max 15db, 1dB each LSB*/
uint8_t rf12CalMgc;
/* RF channel 3&4 calibration mgc: [7:4] Channle3 - max 15db, 1dB each LSB
* [3:0] Channle4 - max 15db, 1dB each LSB*/
uint8_t rf34CalMgc;
/* Receive channel 1-4 MGC: 0~31, 1dB each LSB */
uint8_t rcvMgc;
/* Receive monitor, 0-normal, 1-switch to monitor port */
uint8_t rfMonitor;
/* reserved for further use */
uint8_t rfReserved0;
uint8_t rfReserved1;
uint8_t rfCtrl; ///< [7:4]RF enable: 0-On, 1-Off(Default); [3:0]Work mode: 0(default)
uint8_t rfFreq[2]; ///< 0~3500Mhz, step 1MHz
uint8_t rfTxMgc; ///< RF MGC control: 0~31, 1dB each LSB
uint8_t rf12CalMgc; ///< RF channel 1&2 calibration mgc\n
/// [7:4] Channle1 - max 15db, 1dB each LSB \n
/// [3:0] Channle2 - max 15db, 1dB each LSB
uint8_t rf34CalMgc; ///< RF channel 3&4 calibration mgc\n
/// [7:4] Channle3 - max 15db, 1dB each LSB
/// [3:0] Channle4 - max 15db, 1dB each LSB
uint8_t rcvMgc; ///< Receive channel 1-4 MGC: 0~31, 1dB each LSB
uint8_t rfMonitor; ///< Receive monitor, 0-normal, 1-switch to monitor port
uint8_t rfReserved0; ///< reserved for further use
uint8_t rfReserved1; ///< reserved for further use
uint8_t ch0Cal[2];
uint8_t ch1Cal[2];
uint8_t ch2Cal[2];
uint8_t ch3Cal[2];
} PHY_ANT_CONFIG;
/**
* @struct PHY_ANT_ANGLE
* @brief Describe the PhysicalLayer antenna angle
*/
typedef struct
{
/* off-axis angle range is 0~60,
* 0.1 degree each LSB */
uint16_t oaxis;
/* round-axis angle range is 0~360,
* 0.1 degree each LSB */
uint16_t raxis;
uint16_t oaxis; ///< off-axis angle range is 0~60
/// 0.1 degree each LSB
uint16_t raxis; ///< round-axis angle range is 0~360
/// 0.1 degree each LSB
} PHY_ANT_ANGLE;
/**
* @enum PHY_TIME_WORD_TYPE
*/
typedef enum
{
PHY_TIME_WORD_NONE = 0,
@@ -143,15 +139,21 @@ typedef enum
PHY_TIME_WORD_LISTEN_TIMEOUT = 2
} PHY_TIME_WORD_TYPE;
/**
* @enum PHY_ANT_BEAM_WIDTH
*/
typedef enum
{
PHY_ANT_BEAM_NONE = 0,
PHY_ANT_BEAM_120 = 1,
PHY_ANT_BEAM_60 = 2,
PHY_ANT_BEAM_25 = 3,
PHY_ANT_BEAM_8 = 4
PHY_ANT_BEAM_16 = 4
} PHY_ANT_BEAM_WIDTH;
/**
* @enum PHY_TOR_TYPE
*/
typedef enum
{
PHY_TOR_SUSPEND = 0,
@@ -159,6 +161,9 @@ typedef enum
PHY_TOR_RX = 2
} PHY_TOR_TYPE;
/**
* @enum PHY_MODE
*/
typedef enum
{
PHY_MODE_NONE = 0,
@@ -167,24 +172,21 @@ typedef enum
PHY_MODE_PULL = 3
} PHY_MODE;
/**
* @enum PHY_ANT_MODE
*/
typedef enum
{
PHY_ANT_MODE_NONE = 0,
PHY_ANT_MODE_SILENT = 1,
PHY_ANT_MODE_LOW_POWER = 2,
PHY_ANT_MODE_HIGH_POWER = 3,
PHY_ANT_MODE_STANDBY = 1,
PHY_ANT_MODE_POWER_LOW = 2,
PHY_ANT_MODE_POWER_FULL = 3,
} PHY_ANT_MODE;
typedef struct
{
uint32_t devId;
uint32_t txBramId;
uint32_t rxBramId;
uint32_t antBramId;
uint32_t hwXadcId;
uintptr_t baseAddr;
} PHY_CONFIG;
/**
* @struct PHY_RCD
* @brief Physical Layer recode buffer
*/
typedef struct
{
int32_t last;
@@ -192,83 +194,101 @@ typedef struct
int32_t next;
} PHY_RCD;
/**
* @struct PHY_CONFIG
* @brief struct holds all physical layer initialization parameters
*/
typedef struct
{
PHY_CONFIG phyCofig; // Device address configs
uintptr_t recvDataAddr;
uintptr_t sendDataAddr;
uintptr_t antConfigAddr;
bool isPhyEn; // if physical layer running
bool isAcq; // if last reception acquisition success
bool isFrameSync; // if last reception frame sync success
bool isDecode; // if last reception decode success
bool isValid; // if last reception frame data valid (crc check pass)
bool isPresetHop; // if using preset frequency hop
TIME_WORD recvSlotTime; // last slot start time stamp
TIME_WORD recvFsTime; // last frame sync time stamp
PHY_RCD antNo; // antenna number record
PHY_RCD beamNo; // beam number record
PHY_RCD beamWd; // beam width record
PHY_RCD tor; // tx rx state record
PHY_RCD frameType; // frame type record
uint32_t sendDataOffset; // antenna configuration bram offset (to implement ping-pong data flow)
uint32_t antConfigOffset; // antenna configuration bram offset (to implement ping-pong data flow)
PHY_ANT_CONFIG antConfig; // antenna configuration pointer
uint32_t devId; ///< device ID
uint32_t txBramId; ///< tx bram ID
uint32_t rxBramId; ///< rx bram ID
uint32_t antBramId; ///< antenna config bram ID
uint32_t antInfoBramId; ///< antenna beam info bram ID
uint32_t hwXadcId; ///< hardware xadc device ID
uintptr_t baseAddr; ///< Physical layer controller base address
#ifndef EMULATION
XAdcPs hwXadc;
uint8_t (*get_clk_state)(void); ///< function handle returns hardware clock state
uint8_t (*get_ad_lock_state)(void); ///< function handle returns adc lock state
int8_t (*get_ad0_temp)(void); ///< function handle returns adc0 temperature state
int8_t (*get_ad1_temp)(void); ///< function handle returns adc1 temperature state
#endif
HWSTATE hwSate;
} PHY_CONFIG;
/**
* @struct PHY_INST
* @brief Physical Layer operating instance
*/
typedef struct
{
PHY_CONFIG phyCofig; ///< physical layer configuration parameters
uintptr_t recvDataAddr; ///< receive data bram address
uintptr_t sendDataAddr; ///< send data bram address
uintptr_t antConfigAddr; ///< antenna config data bram address
uintptr_t antInfoAddr; ///< antenna beam info data bram address
bool isPhyEn; ///< indicates if physical layer running
bool isAcq; ///< indicates if last reception acquisition success
bool isFrameSync; ///< indicates if last reception frame sync success
bool isDecode; ///< indicates if last reception decode success
bool isValid; ///< indicates if last reception frame data valid (crc check pass)
TIME_WORD recvSlotTime; ///< last slot start time stamp
TIME_WORD recvFsTime; ///< last frame sync time stamp
PHY_RCD beamNo; ///< beam number record
PHY_RCD beamWd; ///< beam width record
PHY_RCD tor; ///< tx rx state record
PHY_RCD frameType; ///< frame type record
uint32_t sendDataOffset; ///< antenna configuration bram offset (to implement ping-pong data flow)
uint32_t antConfigOffset; ///< antenna configuration bram offset (to implement ping-pong data flow)
PHY_ANT_CONFIG antConfig; ///< antenna configuration pointer
#ifndef EMULATION
XAdcPs hwXadc; ///< hardware Xadc instance
#endif
PHY_ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN]; ///< antenna beam scan pattern
HWSTATE hwSate; ///< hardware state log
PHYLOG phyLog; ///< physical state log
uint32_t lastLogTime; /// physical state log time stamp
} PHY_INST;
/************************** Variable Definitions *****************************/
extern uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS];
extern uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS];
extern uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS];
extern uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS];
extern uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS];
extern uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS];
extern uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS];
extern uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS];
extern uint16_t hopPattern_1M2BPS_5MS[L1_FRAME_1M2BPS_5MS_HOPS];
extern PHY_ANT_ANGLE antSubnrrwPattern[L1_NUM_ANT_SUBNRRW_PATTERN];
extern PHY_ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN];
/************************** Function Prototypes ******************************/
int32_t Phy_InstInit(PHY_INST **instPtr, PHY_CONFIG *phyConfig);
/**
* @defgroup PhysicalLayer_Main
* @{
*/
int32_t Phy_Init(PHY_INST **instPtr, PHY_CONFIG *phyConfig);
void Phy_Destroy(PHY_INST *instPtr);
void Phy_UpdateState(PHY_INST *instPtr);
void Phy_UpdateHwSate(PHY_INST *instPtr);
void Phy_Start(PHY_INST *instPtr);
void Phy_Halt(PHY_INST *instPtr);
int32_t Phy_SetMode(PHY_INST *instPtr, PHY_MODE modeCod);
int32_t Phy_SetMode(PHY_INST *instPtr, PHY_MODE modeCod);
int32_t Phy_SetTimeWord(PHY_INST *instPtr, const TIME_WORD *tmWord, PHY_TIME_WORD_TYPE tmType);
int32_t Phy_SetupNextSlot(PHY_INST *instPtr, PHY_TOR_TYPE txrxMode, L1_FRAME_TYPE frameType, uint8_t *dataBuff);
void Phy_UpdateState(PHY_INST *instPtr);
void Phy_PeekRecvData(PHY_INST *instPtr, uint8_t *dataBuff);
void Phy_RetrieveRecvData(PHY_INST *instPtr, uint8_t *dataBuff);
void Phy_UpdateLogging(PHY_INST *instPtr);
void Phy_RefreshHwSate(PHY_INST *instPtr);
/** @} PhysicalLayer_Main*/
/**
* @defgroup PhysicalLayer_Utility
* @{
*/
bool Phy_IsFrameDetected(PHY_INST *instPtr);
bool Phy_IsFrameReceived(PHY_INST *instPtr);
bool Phy_IsFrameValid(PHY_INST *instPtr);
uint32_t Phy_GetFrameLen(L1_FRAME_TYPE frameType);
L1_FRAME_TYPE Phy_GetLastRecvFrameType(PHY_INST *instPtr);
L1_FRAME_TYPE Phy_GetLastSendFrameType(PHY_INST *instPtr);
int32_t Phy_SetHopPattern(void *patternBuff, uint32_t patternLen);
uint32_t Phy_GetHopLength(L1_FRAME_TYPE frameType);
uint32_t Phy_GetTimeComp(L1_FRAME_TYPE frameType);
L1_FRAME_TYPE Phy_GetLastRecvFrameType(PHY_INST *instPtr);
L1_FRAME_TYPE Phy_GetLastSendFrameType(PHY_INST *instPtr);
/** @} PhysicalLayer_Utility*/
void Phy_AntConfigInit(PHY_ANT_CONFIG *antConfig);
void Phy_AntConfigMode(PHY_INST *instPtr, PHY_ANT_MODE mode);
int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth);
int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo);
int32_t Phy_SetBeamAngle(PHY_INST *phyInstPtr, double offAx, double rndAx);
int32_t Phy_SetTimeWord(PHY_INST *instPtr, const TIME_WORD *tmWord, PHY_TIME_WORD_TYPE tmType);
/**
* @defgroup PhysicalLayer_Receive_Estimations
* @{
*/
uint8_t Phy_LastScanBeamNo(PHY_INST *instPtr);
double Phy_GetFreqEst(PHY_INST *instPtr);
double Phy_GetCoarseFreqEst(PHY_INST *instPtr);
double Phy_GetFineFreqEst(PHY_INST *instPtr);
@@ -276,4 +296,20 @@ void Phy_GetFrameSyncTimeStamp(PHY_INST *instPtr, TIME_WORD *frameSyncT);
void Phy_GetLastReceivedFrameSyncTimeStamp(PHY_INST *instPtr, TIME_WORD *frameSyncT);
void Phy_GetSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotStart);
void Phy_GetLastReceivedSlotStartTimeStamp(PHY_INST *instPtr, TIME_WORD *slotStart);
#endif /* PHY_CTRL_H_ */
/** @} PhysicalLayer_Receive_Estimations*/
/**
* @defgroup PhysicalLayer_AntennaControl
* @{
*/
void Phy_AntConfigInit(PHY_ANT_CONFIG *antConfig);
void Phy_AntConfigMode(PHY_INST *instPtr, PHY_ANT_MODE mode);
void Phy_SetBeamTable(PHY_INST *instPtr, PHY_ANT_ANGLE *table, uint32_t offset);
int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth);
int32_t Phy_SetBeamNo(PHY_INST *instPtr, size_t beamNo, PHY_ANT_BEAM_WIDTH beamWidth);
int32_t Phy_SetBeamAngle(PHY_INST *phyInstPtr, double offAx, double rndAx);
/** @} PhysicalLayer_AntennaControl*/
#endif // PHY_CTRL_H_
/** @} PhysicalLayer*/
+218 -65
View File
@@ -1,24 +1,24 @@
/*****************************************************************************/
/**
* Description: Physical layer register definitions
* @file phy_layer.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Physical layer controller register definition
* @version 0.0
* @date 2023-04-24
*
* Author: Fan Hao
* Date: 2021-11-16 00:08
* LastEditors: Fan Hao
* LastEditTime: 2023-04-24 17:32
* Revisions: Rev 0.1
* History:
* [2021-11-16]: Initial version.
* [2022-06-18]: New branch for glink control purpose:
* -Add poll modephysical layer will start Tx/Rx procedure
* at specific time stamp.
* [2023-04-24]: Porting for DUIFEI.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @defgroup PhysicalLayer
* @{
*/
/**
* @name PhysicalLayer_REG_Constants
* @{
*/
#ifndef PHY_REG_H_
#define PHY_REG_H_
@@ -26,20 +26,23 @@
#include "util.h"
/***************** Macros (Inline Functions) Definitions *********************/
#define PhyRead(instPtr, addr) IO_In32(instPtr->phyCofig.baseAddr + addr)
#define PhyWrite(instPtr, addr, value) IO_Out32(instPtr->phyCofig.baseAddr + addr, value)
#define PhyRead(instPtr, addr) IO_In32((instPtr)->phyCofig.baseAddr + (addr))
#define PhyWrite(instPtr, addr, value) IO_Out32((instPtr)->phyCofig.baseAddr + (addr), (value))
/************************** Constant Definitions *****************************/
/**
* Register: PHY_MAIN_CTRL
*/
#define PHY_MAIN_CTRL 0X00000000U
#define PHY_MAIN_CTRL 0x00000000U
#define PHY_MAIN_CTRL_EN_SHIFT 0
#define PHY_MAIN_CTRL_EN_WIDTH 1
#define PHY_MAIN_CTRL_EN_MASK 0x00000001U
#define PHY_MAIN_CTRL_MODE_SHIFT 8
#define PHY_MAIN_CTRL_MODE_WIDTH 8
#define PHY_MAIN_CTRL_MODE_MASK 0x0000FF00U
#define PHY_MAIN_CTRL_NSCAN_SHIFT 16
#define PHY_MAIN_CTRL_NSCAN_WIDTH 8
#define PHY_MAIN_CTRL_NSCAN_MASK 0x00FF0000U
#define PHY_MAIN_CTRL_EN_EN 0x00000001U
#define PHY_MAIN_CTRL_EN_DSBL 0x00000000U
@@ -275,70 +278,220 @@
#define BEAM_AXIS_AZ_MASK 0xFFFF0000U
/**
* Register: ANT_STATUS_0
* Register: ANT_STATUS
*/
#define ANT_STATUS 0x00000048U
#define ANT_STATUS_CODE_SHIFT 0
#define ANT_STATUS_CODE_WIDTH 8
#define ANT_STATUS_CODE_MASK 0x000000FFU
#define ANT_STATUS_NIL_VOLT_SHIFT 8
#define ANT_STATUS_NIL_VOLT_WIDTH 8
#define ANT_STATUS_NIL_VOLT_MASK 0x0000FF00U
#define ANT_STATUS_RF_VOLT_SHIFT 16
#define ANT_STATUS_RF_VOLT_WIDTH 8
#define ANT_STATUS_RF_VOLT_MASK 0x00FF0000U
#define ANT_STATUS_ANT_VOLT_SHIFT 24
#define ANT_STATUS 0x00000100U
#define ANT_STATUS_ANT_VOLT_SHIFT 0
#define ANT_STATUS_ANT_VOLT_WIDTH 8
#define ANT_STATUS_ANT_VOLT_MASK 0xFF000000U
#define ANT_STATUS_ANT_VOLT_MASK 0x000000FFU
#define ANT_STATUS_ANT_VOLT_OK 0x00000001U
#define ANT_STATUS_RF_VOLT_SHIFT 8
#define ANT_STATUS_RF_VOLT_WIDTH 8
#define ANT_STATUS_RF_VOLT_MASK 0x0000FF00U
#define ANT_STATUS_RF_VOLT_OK 0x00000100U
#define ANT_STATUS_NIL_VOLT_SHIFT 16
#define ANT_STATUS_NIL_VOLT_WIDTH 8
#define ANT_STATUS_NIL_VOLT_MASK 0x00FF0000U
#define ANT_STATUS_NIL_VOLT_OK 0x00010000U
#define ANT_STATUS_CODE_SHIFT 24
#define ANT_STATUS_CODE_WIDTH 8
#define ANT_STATUS_CODE_MASK 0xFF000000U
#define ANT_STATUS_CODE_OK 0x00000000U
/**
* Register: ANT_FRAME_CNT
*/
#define ANT_FRAME_CNT 0x0000004CU
#define ANT_FRAME_CNT 0x00000104U
#define ANT_FRAME_CNT_SHIFT 0
#define ANT_FRAME_CNT_WIDTH 32
#define ANT_FRAME_CNT_MASK 0xFFFFFFFFU
/**
* Register: RF_STATUS
* Register: ANT_RF_STATUS
*/
#define RF_STATUS 0x00000050U
#define RF_STATUS_TEMP_SHIFT 0
#define RF_STATUS_TEMP_WIDTH 8
#define RF_STATUS_TEMP_MASK 0x000000FFU
#define RF_STATUS_BDLOCK_SHIFT 8
#define RF_STATUS_BDLOCK_WIDTH 8
#define RF_STATUS_BDLOCK_MASK 0x0000FF00U
#define RF_STATUS_PLLA_SHIFT 16
#define RF_STATUS_PLLA_WIDTH 8
#define RF_STATUS_PLLA_MASK 0x00FF0000U
#define RF_STATUS_PLLB_SHIFT 24
#define RF_STATUS_PLLB_WIDTH 8
#define RF_STATUS_PLLB_MASK 0xFF000000U
#define ANT_RF_STATUS 0x00000108U
#define ANT_RF_STATUS_TEMP_SHIFT 0
#define ANT_RF_STATUS_TEMP_WIDTH 8
#define ANT_RF_STATUS_TEMP_MASK 0x000000FFU
#define ANT_RF_STATUS_BBLOCK_SHIFT 8
#define ANT_RF_STATUS_BBLOCK_WIDTH 8
#define ANT_RF_STATUS_BBLOCK_MASK 0x0000FF00U
#define ANT_RF_STATUS_BBLOCK_OK 0x00000100U
#define ANT_RF_STATUS_PLLA_SHIFT 16
#define ANT_RF_STATUS_PLLA_WIDTH 8
#define ANT_RF_STATUS_PLLA_MASK 0x00FF0000U
#define ANT_RF_STATUS_PLLA_OK 0x00010000U
#define ANT_RF_STATUS_PLLB_SHIFT 24
#define ANT_RF_STATUS_PLLB_WIDTH 8
#define ANT_RF_STATUS_PLLB_MASK 0xFF000000U
#define ANT_RF_STATUS_PLLB_OK 0x01000000U
/**
* Register: RF_MGC
* Register: ANT_RF_MGC
*/
#define RF_MGC 0x00000054U
#define RF_MGC_CH1_SHIFT 0
#define RF_MGC_CH1_WIDTH 4
#define RF_MGC_CH1_MASK 0x0000000FU
#define RF_MGC_CH2_SHIFT 8
#define RF_MGC_CH2_WIDTH 4
#define RF_MGC_CH2_MASK 0x00000F00U
#define RF_MGC_CH3_SHIFT 16
#define RF_MGC_CH3_WIDTH 4
#define RF_MGC_CH3_MASK 0x000F0000U
#define RF_MGC_CH4_SHIFT 24
#define RF_MGC_CH4_WIDTH 4
#define RF_MGC_CH4_MASK 0x0F000000U
#define ANT_RF_MGC 0x0000010CU
#define ANT_RF_MGC_CH1_SHIFT 0
#define ANT_RF_MGC_CH1_WIDTH 4
#define ANT_RF_MGC_CH1_MASK 0x0000000FU
#define ANT_RF_MGC_CH2_SHIFT 8
#define ANT_RF_MGC_CH2_WIDTH 4
#define ANT_RF_MGC_CH2_MASK 0x00000F00U
#define ANT_RF_MGC_CH3_SHIFT 16
#define ANT_RF_MGC_CH3_WIDTH 4
#define ANT_RF_MGC_CH3_MASK 0x000F0000U
#define ANT_RF_MGC_CH4_SHIFT 24
#define ANT_RF_MGC_CH4_WIDTH 4
#define ANT_RF_MGC_CH4_MASK 0x0F000000U
/**
* Register: RF_FRAME_CNT
* Register: ANT_RF_FRAME_CNT
*/
#define RF_FRAME_CNT 0x00000058U
#define RF_FRAME_CNT_SHIFT 0
#define RF_FRAME_CNT_WIDTH 32
#define RF_FRAME_CNT_MASK 0xFFFFFFFFU
#define ANT_RF_FRAME_CNT 0x00000110U
#define ANT_RF_FRAME_CNT_SHIFT 0
#define ANT_RF_FRAME_CNT_WIDTH 32
#define ANT_RF_FRAME_CNT_MASK 0xFFFFFFFFU
/**
* Register: PHY_ACQ_CNT
*/
#define PHY_ACQ_CNT 0x00000114U
#define PHY_ACQ_CNT_SHIFT 0
#define PHY_ACQ_CNT_WIDTH 32
#define PHY_ACQ_CNT_MASK 0xFFFFFFFFU
/**
* Register: PHY_FRAME_SYNC_CNT
*/
#define PHY_FRAME_SYNC_CNT 0x00000118U
#define PHY_FRAME_SYNC_CNT_SHIFT 0
#define PHY_FRAME_SYNC_CNT_WIDTH 32
#define PHY_FRAME_SYNC_CNT_MASK 0xFFFFFFFFU
/**
* Register: PHY_DECODE_CNT
*/
#define PHY_DECODE_CNT 0x0000011CU
#define PHY_DECODE_CNT_SHIFT 0
#define PHY_DECODE_CNT_WIDTH 32
#define PHY_DECODE_CNT_MASK 0xFFFFFFFFU
/**
* Register: PHY_CRC_OK_CNT
*/
#define PHY_CRC_OK_CNT 0x00000120U
#define PHY_CRC_OK_CNT_SHIFT 0
#define PHY_CRC_OK_CNT_WIDTH 32
#define PHY_CRC_OK_CNT_MASK 0xFFFFFFFFU
/**
* Register: PHY_ACQ_PEAK_H
*/
#define PHY_ACQ_PEAK_H 0x00000124U
#define PHY_ACQ_PEAK_H_SHIFT 0
#define PHY_ACQ_PEAK_H_WIDTH 32
#define PHY_ACQ_PEAK_H_MASK 0xFFFFFFFFU
/**
* Register: PHY_ACQ_PEAK_L
*/
#define PHY_ACQ_PEAK_L 0x00000128U
#define PHY_ACQ_PEAK_L_SHIFT 0
#define PHY_ACQ_PEAK_L_WIDTH 32
#define PHY_ACQ_PEAK_L_MASK 0xFFFFFFFFU
/**
* Register: PHY_ACQ_MEAN_H
*/
#define PHY_ACQ_MEAN_H 0x0000012CU
#define PHY_ACQ_MEAN_H_SHIFT 0
#define PHY_ACQ_MEAN_H_WIDTH 32
#define PHY_ACQ_MEAN_H_MASK 0xFFFFFFFFU
/**
* Register: PHY_ACQ_MEAN_L
*/
#define PHY_ACQ_MEAN_L 0x00000130U
#define PHY_ACQ_MEAN_L_SHIFT 0
#define PHY_ACQ_MEAN_L_WIDTH 32
#define PHY_ACQ_MEAN_L_MASK 0xFFFFFFFFU
/**
* Register: PHY_ACQ_FREQEST
*/
#define PHY_ACQ_FREQEST 0x00000134U
#define PHY_ACQ_FREQEST_SHIFT 0
#define PHY_ACQ_FREQEST_WIDTH 32
#define PHY_ACQ_FREQEST_MASK 0xFFFFFFFFU
#define PHY_ACQ_FREQEST_PHASE_SHIFT 0
#define PHY_ACQ_FREQEST_PHASE_WIDTH 8
#define PHY_ACQ_FREQEST_PHASE_MASK 0x000000FFU
#define PHY_ACQ_FREQEST_CHANNEL_SHIFT 8
#define PHY_ACQ_FREQEST_CHANNEL_WIDTH 8
#define PHY_ACQ_FREQEST_CHANNEL_MASK 0x0000FF00U
/**
* Register: PHY_FRAME_SYNC_PEAK_H
*/
#define PHY_FRAME_SYNC_PEAK_H 0x00000138U
#define PHY_FRAME_SYNC_PEAK_H_SHIFT 0
#define PHY_FRAME_SYNC_PEAK_H_WIDTH 32
#define PHY_FRAME_SYNC_PEAK_H_MASK 0xFFFFFFFFU
/**
* Register: PHY_FRAME_SYNC_PEAK_L
*/
#define PHY_FRAME_SYNC_PEAK_L 0x0000013CU
#define PHY_FRAME_SYNC_PEAK_L_SHIFT 0
#define PHY_FRAME_SYNC_PEAK_L_WIDTH 32
#define PHY_FRAME_SYNC_PEAK_L_MASK 0xFFFFFFFFU
/**
* Register: PHY_FRAME_SYNC_MEAN_H
*/
#define PHY_FRAME_SYNC_MEAN_H 0x00000140U
#define PHY_FRAME_SYNC_MEAN_H_SHIFT 0
#define PHY_FRAME_SYNC_MEAN_H_WIDTH 32
#define PHY_FRAME_SYNC_MEAN_H_MASK 0xFFFFFFFFU
/**
* Register: PHY_FRAME_SYNC_MEAN_L
*/
#define PHY_FRAME_SYNC_MEAN_L 0x00000144U
#define PHY_FRAME_SYNC_MEAN_L_SHIFT 0
#define PHY_FRAME_SYNC_MEAN_L_WIDTH 32
#define PHY_FRAME_SYNC_MEAN_L_MASK 0xFFFFFFFFU
/**
* Register: PHY_FRAME_SYNC_FREQEST
*/
#define PHY_FRAME_SYNC_FREQEST 0x00000148U
#define PHY_FRAME_SYNC_FREQEST_SHIFT 0
#define PHY_FRAME_SYNC_FREQEST_WIDTH 32
#define PHY_FRAME_SYNC_FREQEST_MASK 0xFFFFFFFFU
#define PHY_FRAME_SYNC_FREQEST_CHANNEL_SHIFT 0
#define PHY_FRAME_SYNC_FREQEST_CHANNEL_WIDTH 8
#define PHY_FRAME_SYNC_FREQEST_CHANNEL_MASK 0x000000FFU
/**
* Register: PHY_DEINTLV_AMPEST
*/
#define PHY_DEINTLV_AMPEST 0x0000014CU
#define PHY_DEINTLV_AMPEST_SHIFT 0
#define PHY_DEINTLV_AMPEST_WIDTH 16
#define PHY_DEINTLV_AMPEST_MASK 0x0000FFFFU
#endif /* PHY_REG_H_ */
/** @} PhysicalLayer_REG_Constants*/
/** @} PhysicalLayer*/
+218 -376
View File
@@ -1,9 +1,19 @@
/**
* @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
@@ -13,38 +23,47 @@
#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;
uint8_t rBusy;
uint8_t wBusy;
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 recvPLCtrl;
PAYLOAD recvPL[2];
PINGPONG sendPLCtrl;
PAYLOAD sendPL[2];
PINGPONG recvCtrl;
PAYLOAD recv[2];
PINGPONG sendCtrl;
PAYLOAD send[2];
PINGPONG sysInfoCtrl;
SYSINFO sysInfo[2];
PINGPONG sendLogCtrl;
SLOTLOG sendLog[2];
PINGPONG recvLogCtrl;
SLOTLOG recvLog[2];
PINGPONG protocolLogCtrl;
PRTCLLOG protocolLog[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;
uint8_t GetWritable(PINGPONG ctrllor);
uint8_t GetReadable(PINGPONG ctrllor);
inline uint8_t GetWritable(PINGPONG ctrllor)
/*********************** Function Implementations ***************************/
inline static uint8_t GetWritable(PINGPONG ctrllor)
{
// Allow only one write.
ASSERT(ctrllor.wBusy == BUFF_NONE);
@@ -54,7 +73,7 @@ inline uint8_t GetWritable(PINGPONG ctrllor)
return ((ctrllor.rBusy == BUFF_B) ? BUFF_A : BUFF_B);
}
inline uint8_t GetReadable(PINGPONG ctrllor)
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);
@@ -62,7 +81,11 @@ inline uint8_t GetReadable(PINGPONG ctrllor)
return ((ctrllor.wBusy == BUFF_B) ? BUFF_A : BUFF_B);
}
// System monitor initialise
/**
* @brief Initialize System monitor
*
* @return SUCCESS
*/
int32_t SysMonitor_Init(void)
{
sysMonitorInst = calloc(1, sizeof(SYSMONITOR));
@@ -70,30 +93,41 @@ int32_t SysMonitor_Init(void)
{
return ENOMEM;
}
memset(&(sysMonitorInst->recvPLCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->sendPLCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->recvCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->sendCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->sysInfoCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->sendLogCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->recvLogCtrl), BUFF_NONE, sizeof(PINGPONG));
memset(&(sysMonitorInst->protocolLogCtrl), 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->recvPL[0].dataId = DATA_ID_NONE;
sysMonitorInst->recvPL[1].dataId = DATA_ID_NONE;
sysMonitorInst->sendPL[0].dataId = DATA_ID_NONE;
sysMonitorInst->sendPL[1].dataId = DATA_ID_NONE;
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;
}
// System monitor initialise
/**
* @brief Destroy system monitor release all allocated memory
*/
void SysMonitor_Destroy(void)
{
free(sysMonitorInst);
}
// @System Info
void SysMonitor_UpdateSysinfo(SYSINFO *info)
/**
* @name SystemInfo_API
* @{
*/
/**
* @brief Update system info.
*
* @param info
*/
void SysMonitor_UpdateSysinfo(const SYSINFO *info)
{
ASSERT(info != NULL);
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->sysInfoCtrl);
sysMonitorInst->sysInfoCtrl.wBusy = buffIndx;
@@ -102,52 +136,15 @@ void SysMonitor_UpdateSysinfo(SYSINFO *info)
sysMonitorInst->sysInfoCtrl.wBusy = BUFF_NONE;
}
void SysMonitor_UpdateSysinfoRaw(uint8_t *buff)
{
ASSERT(sysMonitorInst != NULL);
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->sysInfoCtrl);
sysMonitorInst->sysInfoCtrl.wBusy = buffIndx;
// Decapsulate Systeminfo
SYSINFO *infoEntry = &(sysMonitorInst->sysInfo[buffIndx]);
memcpy(&(infoEntry->psBDS), buff, sizeof(infoEntry->psBDS));
buff += sizeof(infoEntry->psBDS);
memcpy(&(infoEntry->pBDS), buff, sizeof(infoEntry->pBDS));
buff += sizeof(infoEntry->pBDS);
memcpy(&(infoEntry->psGPS), buff, sizeof(infoEntry->psGPS));
buff += sizeof(infoEntry->psGPS);
memcpy(&(infoEntry->pGPS), buff, sizeof(infoEntry->pGPS));
buff += sizeof(infoEntry->pGPS);
memcpy(&(infoEntry->tmInd), buff, sizeof(infoEntry->tmInd));
buff += sizeof(infoEntry->tmInd);
memcpy(&(infoEntry->tmFly), buff, sizeof(infoEntry->tmFly));
buff += sizeof(infoEntry->tmFly);
memcpy(&(infoEntry->stFly), buff, sizeof(infoEntry->stFly));
buff += sizeof(infoEntry->stFly);
memcpy(&(infoEntry->posX), buff, sizeof(infoEntry->posX));
buff += sizeof(infoEntry->posX);
memcpy(&(infoEntry->posY), buff, sizeof(infoEntry->posY));
buff += sizeof(infoEntry->posY);
memcpy(&(infoEntry->posZ), buff, sizeof(infoEntry->posZ));
buff += sizeof(infoEntry->posZ);
memcpy(&(infoEntry->vX), buff, sizeof(infoEntry->vX));
buff += sizeof(infoEntry->vX);
memcpy(&(infoEntry->vY), buff, sizeof(infoEntry->vY));
buff += sizeof(infoEntry->vY);
memcpy(&(infoEntry->vZ), buff, sizeof(infoEntry->vZ));
buff += sizeof(infoEntry->vZ);
memcpy(&(infoEntry->pitch), buff, sizeof(infoEntry->pitch));
buff += sizeof(infoEntry->pitch);
memcpy(&(infoEntry->yaw), buff, sizeof(infoEntry->yaw));
buff += sizeof(infoEntry->yaw);
memcpy(&(infoEntry->roll), buff, sizeof(infoEntry->roll));
sysMonitorInst->sysInfoCtrl.latest = buffIndx;
sysMonitorInst->sysInfoCtrl.wBusy = BUFF_NONE;
}
/**
* @brief Get system info.
*
* @param info
*/
void SysMonitor_GetSysinfo(SYSINFO *info)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(info != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->sysInfoCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
@@ -158,326 +155,226 @@ void SysMonitor_GetSysinfo(SYSINFO *info)
memcpy(info, &(sysMonitorInst->sysInfo[buffIndx]), sizeof(SYSINFO));
sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old;
}
/** @} SystemInfo_API*/
void SysMonitor_GetSysinfoRaw(uint8_t *buff)
{
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;
// Encapsulate Systeminfo
SYSINFO *infoEntry = &(sysMonitorInst->sysInfo[buffIndx]);
memcpy(buff, &(infoEntry->psBDS), sizeof(infoEntry->psBDS));
buff += sizeof(infoEntry->psBDS);
memcpy(buff, &(infoEntry->pBDS), sizeof(infoEntry->pBDS));
buff += sizeof(infoEntry->pBDS);
memcpy(buff, &(infoEntry->psGPS), sizeof(infoEntry->psGPS));
buff += sizeof(infoEntry->psGPS);
memcpy(buff, &(infoEntry->pGPS), sizeof(infoEntry->pGPS));
buff += sizeof(infoEntry->pGPS);
memcpy(buff, &(infoEntry->tmInd), sizeof(infoEntry->tmInd));
buff += sizeof(infoEntry->tmInd);
memcpy(buff, &(infoEntry->tmFly), sizeof(infoEntry->tmFly));
buff += sizeof(infoEntry->tmFly);
memcpy(buff, &(infoEntry->stFly), sizeof(infoEntry->stFly));
buff += sizeof(infoEntry->stFly);
memcpy(buff, &(infoEntry->posX), sizeof(infoEntry->posX));
buff += sizeof(infoEntry->posX);
memcpy(buff, &(infoEntry->posY), sizeof(infoEntry->posY));
buff += sizeof(infoEntry->posY);
memcpy(buff, &(infoEntry->posZ), sizeof(infoEntry->posZ));
buff += sizeof(infoEntry->posZ);
memcpy(buff, &(infoEntry->vX), sizeof(infoEntry->vX));
buff += sizeof(infoEntry->vX);
memcpy(buff, &(infoEntry->vY), sizeof(infoEntry->vY));
buff += sizeof(infoEntry->vY);
memcpy(buff, &(infoEntry->vZ), sizeof(infoEntry->vZ));
buff += sizeof(infoEntry->vZ);
memcpy(buff, &(infoEntry->pitch), sizeof(infoEntry->pitch));
buff += sizeof(infoEntry->pitch);
memcpy(buff, &(infoEntry->yaw), sizeof(infoEntry->yaw));
buff += sizeof(infoEntry->yaw);
memcpy(buff, &(infoEntry->roll), sizeof(infoEntry->roll));
sysMonitorInst->sysInfoCtrl.rBusy = buffIndex_old;
}
// @Send Payload
/**
* Update send payload by raw data.
* @name ServicePayload_API
* @{
*/
void SysMonitor_UpdateSendPayloadRaw(uint8_t *buff, size_t len)
/**
* @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->sendPLCtrl);
sysMonitorInst->sendPLCtrl.wBusy = buffIndx;
memcpy(sysMonitorInst->sendPL[buffIndx].data, buff, len);
sysMonitorInst->sendPL[buffIndx].dataId++;
sysMonitorInst->sendPLCtrl.latest = buffIndx;
sysMonitorInst->sendPLCtrl.wBusy = BUFF_NONE;
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;
}
/**
* Get send payload as raw data.
* @brief Get the latest send payload.
*
* @param buff
* @param id
* @param len
*/
void SysMonitor_GetSendPayloadRaw(uint8_t *buff, uint32_t *id, size_t 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->sendPLCtrl.rBusy;
buffIndex_old = sysMonitorInst->sendCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->sendPLCtrl);
sysMonitorInst->sendPLCtrl.rBusy = buffIndx;
if (sysMonitorInst->sendPL[buffIndx].dataId != DATA_ID_NONE)
{
memcpy(buff, sysMonitorInst->sendPL[buffIndx].data, len);
buffIndx = buffIndex_old; // Keep it busy
}
*id = sysMonitorInst->sendPL[buffIndx].dataId;
sysMonitorInst->sendPLCtrl.rBusy = buffIndex_old;
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;
}
// @Receive Payload
/**
* Update receive payload by raw data.
* @brief Update receive payload.
*
* @param buff
* @param id
* @param len
*/
void SysMonitor_UpdateRecvPayloadRaw(uint8_t *buff, size_t 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->recvPLCtrl);
sysMonitorInst->recvPLCtrl.wBusy = buffIndx;
memcpy(sysMonitorInst->recvPL[buffIndx].data, buff, len);
sysMonitorInst->recvPL[buffIndx].dataId++;
sysMonitorInst->recvPLCtrl.latest = buffIndx;
sysMonitorInst->recvPLCtrl.wBusy = BUFF_NONE;
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;
}
/**
* Get send payload as raw data.
* @brief Get the latest receive payload.
*
* @param buff
* @param id
* @param len
*/
void SysMonitor_GetRecvPayloadRaw(uint8_t *buff, uint32_t *id, size_t 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->recvPLCtrl.rBusy;
buffIndex_old = sysMonitorInst->recvCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->recvPLCtrl);
sysMonitorInst->recvPLCtrl.rBusy = buffIndx;
if (sysMonitorInst->recvPL[buffIndx].dataId != DATA_ID_NONE)
buffIndx = GetReadable(sysMonitorInst->recvCtrl);
sysMonitorInst->recvCtrl.rBusy = buffIndx;
if (sysMonitorInst->recv[buffIndx].dataId != DATA_ID_NONE)
{
memcpy(buff, sysMonitorInst->recvPL[buffIndx].data, len);
memcpy(buff, sysMonitorInst->recv[buffIndx].data, len);
}
*id = sysMonitorInst->recvPL[buffIndx].dataId;
sysMonitorInst->recvPLCtrl.rBusy = buffIndex_old;
*id = sysMonitorInst->recv[buffIndx].dataId;
sysMonitorInst->recvCtrl.rBusy = buffIndex_old;
}
/** @} ServicePayload_API*/
// @Send Slot log
/**
* Log send slot information
* @name Linklayer_Log_API
* @{
*/
void SysMonitor_UpdateSendSlotLog(SLOTLOG *log)
/**
* @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->sendLogCtrl);
sysMonitorInst->sendLogCtrl.wBusy = buffIndx;
memcpy(&(sysMonitorInst->sendLog[buffIndx]), log, sizeof(SLOTLOG));
sysMonitorInst->sendLogCtrl.latest = buffIndx;
sysMonitorInst->sendLogCtrl.wBusy = BUFF_NONE;
buffIndx = GetWritable(sysMonitorInst->linkLogCtrl);
sysMonitorInst->linkLogCtrl.wBusy = buffIndx;
memcpy(&(sysMonitorInst->linkLog[buffIndx]), log, sizeof(LINKLOG));
sysMonitorInst->linkLogCtrl.latest = buffIndx;
sysMonitorInst->linkLogCtrl.wBusy = BUFF_NONE;
}
/**
* Get the latest send slot log
* @brief Get the latest link layer log
*
* @param log
*/
void SysMonitor_GetSendSlotLog(SLOTLOG *log)
void SysMonitor_GetLinklayerLog(LINKLOG *log)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->sendLogCtrl.rBusy;
buffIndex_old = sysMonitorInst->linkLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->sendLogCtrl);
sysMonitorInst->sendLogCtrl.rBusy = buffIndx;
memcpy(log, &(sysMonitorInst->sendLog[buffIndx]), sizeof(SLOTLOG));
sysMonitorInst->sendLogCtrl.rBusy = buffIndex_old;
buffIndx = GetReadable(sysMonitorInst->linkLogCtrl);
sysMonitorInst->linkLogCtrl.rBusy = buffIndx;
memcpy(log, &(sysMonitorInst->linkLog[buffIndx]), sizeof(LINKLOG));
sysMonitorInst->linkLogCtrl.rBusy = buffIndex_old;
}
/** @} Linklayer_Log_API*/
/**
* Get the latest send slot log as raw data
* @name PhysicalLayer_Log_API
* @{
*/
void SysMonitor_GetSendSlotLogRaw(uint8_t *buff)
{
ASSERT(sysMonitorInst != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->sendLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->sendLogCtrl);
sysMonitorInst->sendLogCtrl.rBusy = buffIndx;
// Encapsulate log
SLOTLOG *logEntry = &(sysMonitorInst->sendLog[buffIndx]);
memcpy(buff, &(logEntry->tuNo), sizeof(logEntry->tuNo));
buff += sizeof(logEntry->tuNo);
memcpy(buff, &(logEntry->slotNo), sizeof(logEntry->slotNo));
buff += sizeof(logEntry->slotNo);
memcpy(buff, &(logEntry->frameType), sizeof(logEntry->frameType));
buff += sizeof(logEntry->frameType);
memcpy(buff, &(logEntry->payload), sizeof(logEntry->payload));
buff += sizeof(logEntry->payload);
memcpy(buff, &(logEntry->tmStamp), sizeof(logEntry->tmStamp));
buff += sizeof(logEntry->tmStamp);
memcpy(buff, &(logEntry->tmDevi), sizeof(logEntry->tmDevi));
buff += sizeof(logEntry->tmDevi);
memcpy(buff, &(logEntry->freqDevi), sizeof(logEntry->freqDevi));
sysMonitorInst->sendLogCtrl.rBusy = buffIndex_old;
}
// @Receive Slot log
/**
* Log receive slot information
* @brief Update physical layer log
*
* @param log
*/
void SysMonitor_UpdateRecvSlotLog(SLOTLOG *log)
void SysMonitor_UpdatePhysicalLayerLog(const PHYLOG *log)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->recvLogCtrl);
sysMonitorInst->recvLogCtrl.wBusy = buffIndx;
memcpy(&(sysMonitorInst->recvLog[buffIndx]), log, sizeof(SLOTLOG));
sysMonitorInst->recvLogCtrl.latest = buffIndx;
sysMonitorInst->recvLogCtrl.wBusy = BUFF_NONE;
buffIndx = GetWritable(sysMonitorInst->phyLogCtrl);
sysMonitorInst->phyLogCtrl.wBusy = buffIndx;
memcpy(&(sysMonitorInst->phyLog[buffIndx]), log, sizeof(PHYLOG));
sysMonitorInst->phyLogCtrl.latest = buffIndx;
sysMonitorInst->phyLogCtrl.wBusy = BUFF_NONE;
}
/**
* Get the latest receive slot information
* @brief Get the latest physical layer log
*
* @param log
*/
void SysMonitor_GetRecvSlotLog(SLOTLOG *log)
void SysMonitor_GetPhysicalLayerLog(PHYLOG *log)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(log != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->recvLogCtrl.rBusy;
buffIndex_old = sysMonitorInst->phyLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->recvLogCtrl);
sysMonitorInst->recvLogCtrl.rBusy = buffIndx;
memcpy(log, &(sysMonitorInst->recvLog[buffIndx]), sizeof(SLOTLOG));
sysMonitorInst->recvLogCtrl.rBusy = buffIndex_old;
buffIndx = GetReadable(sysMonitorInst->phyLogCtrl);
sysMonitorInst->phyLogCtrl.rBusy = buffIndx;
memcpy(log, &(sysMonitorInst->phyLog[buffIndx]), sizeof(PHYLOG));
sysMonitorInst->phyLogCtrl.rBusy = buffIndex_old;
}
/** @} */
/**
* Get the latest receive slot information as raw data
* @name HardwareState_Log_API
* @{
*/
void SysMonitor_GetRecvSlotLogRaw(uint8_t *buff)
{
ASSERT(sysMonitorInst != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->recvLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->recvLogCtrl);
sysMonitorInst->recvLogCtrl.rBusy = buffIndx;
// Encapsulate log
SLOTLOG *logEntry = &(sysMonitorInst->recvLog[buffIndx]);
memcpy(buff, &(logEntry->tuNo), sizeof(logEntry->tuNo));
buff += sizeof(logEntry->tuNo);
memcpy(buff, &(logEntry->slotNo), sizeof(logEntry->slotNo));
buff += sizeof(logEntry->slotNo);
memcpy(buff, &(logEntry->frameType), sizeof(logEntry->frameType));
buff += sizeof(logEntry->frameType);
memcpy(buff, &(logEntry->payload), sizeof(logEntry->payload));
buff += sizeof(logEntry->payload);
memcpy(buff, &(logEntry->tmStamp), sizeof(logEntry->tmStamp));
buff += sizeof(logEntry->tmStamp);
memcpy(buff, &(logEntry->tmDevi), sizeof(logEntry->tmDevi));
buff += sizeof(logEntry->tmDevi);
memcpy(buff, &(logEntry->freqDevi), sizeof(logEntry->freqDevi));
sysMonitorInst->recvLogCtrl.rBusy = buffIndex_old;
}
// @Protocol log
/**
* Log protocol running status.
*/
void SysMonitor_UpdateProtocolLog(PRTCLLOG *log)
{
ASSERT(sysMonitorInst != NULL);
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->protocolLogCtrl);
sysMonitorInst->protocolLogCtrl.wBusy = buffIndx;
memcpy(&(sysMonitorInst->protocolLog[buffIndx]), log, sizeof(PRTCLLOG));
sysMonitorInst->protocolLogCtrl.latest = buffIndx;
sysMonitorInst->protocolLogCtrl.wBusy = BUFF_NONE;
}
/**
* Get the protocol running log.
* @brief Log hardware running status.
*
* @param state
*/
void SysMonitor_GetProtocolLog(PRTCLLOG *log)
{
ASSERT(sysMonitorInst != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->protocolLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->protocolLogCtrl);
sysMonitorInst->protocolLogCtrl.rBusy = buffIndx;
memcpy(log, &(sysMonitorInst->protocolLog[buffIndx]), sizeof(PRTCLLOG));
sysMonitorInst->protocolLogCtrl.rBusy = buffIndex_old;
}
/**
* Get the protocol running log as raw data.
*/
void SysMonitor_GetProtocolLogRaw(uint8_t *buff)
{
ASSERT(sysMonitorInst != NULL);
uint8_t buffIndx, buffIndex_old;
buffIndex_old = sysMonitorInst->protocolLogCtrl.rBusy;
if (buffIndex_old != BUFF_NONE)
buffIndx = buffIndex_old; // Keep it busy
else
buffIndx = GetReadable(sysMonitorInst->protocolLogCtrl);
sysMonitorInst->protocolLogCtrl.rBusy = buffIndx;
// Encapsulate log
PRTCLLOG *logEntry = &(sysMonitorInst->protocolLog[buffIndx]);
memcpy(buff, &(logEntry->tmSys), sizeof(logEntry->tmSys));
buff += sizeof(logEntry->tmSys);
memcpy(buff, &(logEntry->phySt), sizeof(logEntry->phySt));
buff += sizeof(logEntry->phySt);
memcpy(buff, &(logEntry->tmLocal), sizeof(logEntry->tmLocal));
buff += sizeof(logEntry->tmLocal);
memcpy(buff, &(logEntry->beamNo), sizeof(logEntry->beamNo));
buff += sizeof(logEntry->beamNo);
memcpy(buff, &(logEntry->beamWidth), sizeof(logEntry->beamWidth));
buff += sizeof(logEntry->beamWidth);
memcpy(buff, &(logEntry->stage), sizeof(logEntry->stage));
buff += sizeof(logEntry->stage);
memcpy(buff, &(logEntry->recvCnt), sizeof(logEntry->recvCnt));
buff += sizeof(logEntry->recvCnt);
sysMonitorInst->protocolLogCtrl.rBusy = buffIndex_old;
}
// @Hardware state
/**
* Log hardware running status.
*/
void SysMonitor_UpdateHardwareStatus(HWSTATE *state)
void SysMonitor_UpdateHardwareStatus(const HWSTATE *state)
{
ASSERT(sysMonitorInst != NULL);
ASSERT(state != NULL);
uint8_t buffIndx;
buffIndx = GetWritable(sysMonitorInst->hwStateCtrl);
sysMonitorInst->hwStateCtrl.wBusy = buffIndx;
@@ -487,11 +384,14 @@ void SysMonitor_UpdateHardwareStatus(HWSTATE *state)
}
/**
* Get the latest hardware running status.
* @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)
@@ -503,64 +403,6 @@ void SysMonitor_GetHardwareStatus(HWSTATE *state)
sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old;
}
/**
* Get the latest hardware running status as raw data.
*/
void SysMonitor_GetHardwareStatusRaw(uint8_t *buff)
{
ASSERT(sysMonitorInst != 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;
/** @} HardwareState_Log_API */
// Encapsulate state
HWSTATE *stateEntry = &(sysMonitorInst->hwState[buffIndx]);
memcpy(buff, &(stateEntry->spVolt), sizeof(stateEntry->spVolt));
buff += sizeof(stateEntry->spVolt);
memcpy(buff, &(stateEntry->spTemp), sizeof(stateEntry->spTemp));
buff += sizeof(stateEntry->spTemp);
memcpy(buff, &(stateEntry->chipSt), sizeof(stateEntry->chipSt));
buff += sizeof(stateEntry->chipSt);
memcpy(buff, &(stateEntry->antVolt), sizeof(stateEntry->antVolt));
buff += sizeof(stateEntry->antVolt);
memcpy(buff, &(stateEntry->antTemp), sizeof(stateEntry->antTemp));
buff += sizeof(stateEntry->antTemp);
memcpy(buff, &(stateEntry->antPll), sizeof(stateEntry->antPll));
buff += sizeof(stateEntry->antPll);
memcpy(buff, &(stateEntry->antMgc), sizeof(stateEntry->antMgc));
buff += sizeof(stateEntry->antMgc);
memcpy(buff, &(stateEntry->antSt), sizeof(stateEntry->antSt));
sysMonitorInst->hwStateCtrl.rBusy = buffIndex_old;
}
// @System log
/**
* Get the latest system running log.
*/
void SysMonitor_GetSyslog(SYSLOG *log)
{
ASSERT(sysMonitorInst != NULL);
SysMonitor_GetSendSlotLog(&(log->sendLog));
SysMonitor_GetRecvSlotLog(&(log->recvLog));
SysMonitor_GetProtocolLog(&(log->protocolLog));
SysMonitor_GetHardwareStatus(&(log->hwSate));
}
/**
* Get the latest system running log as raw data.
*/
void SysMonitor_GetSyslogRaw(uint8_t *buff)
{
ASSERT(sysMonitorInst != NULL);
SysMonitor_GetSendSlotLogRaw(buff);
buff += SLOTLOG_PACK_LEN;
SysMonitor_GetRecvSlotLogRaw(buff);
buff += SLOTLOG_PACK_LEN;
SysMonitor_GetProtocolLogRaw(buff);
buff += PRTCLLOG_PACK_ELN;
SysMonitor_GetHardwareStatusRaw(buff);
}
/** @} SystemMonitor*/
+206 -123
View File
@@ -1,9 +1,21 @@
/**
* @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
@@ -13,146 +25,217 @@
#define DATA_ID_NONE UINT32_MAX
#define DATA_ID_TEST 0x02030203
typedef struct
{
// FIXME: To Complete
uint8_t dummy;
} SYSCONFIG;
#define VOLTAGE_LSB 0.01 // volt
#define VOLTAGE_MAX 2.55 // volt
typedef struct
#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_PLL0_LOCK BIT(0)
#define CLK_SP_PLL1_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))
{
// -- unit: ms, 0~604799999
uint32_t psBDS;
// -- unit: week, 0~0~8191
uint16_t pBDS;
// -- unit: ms, 0~604799999
uint32_t psGPS;
// -- unit: week, 0~0~8191
uint16_t pGPS;
// Time validation indicator
// -- [0] GPS
// -- [1] reserve.
// -- [2] UTC
// -- [3] BDS
uint8_t tmInd;
// Time of flying
// uint: s
float tmFly;
// Status of flying
// [7:6] departure status 11 - departed/00 - not departed
// [5:4] ready status 11 - ready/00 - not ready
// [3:2] attitude status 11 - attitude ok/00 - attitude not ok
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
uint8_t stFly;
// Position in launch coordinate system
float posX;
float posY;
float posZ;
// Speed in launch coordinate system
float vX;
float vY;
float vZ;
// Attitude in launch inertia coordinate system
float pitch;
float yaw;
float roll;
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
int8_t spAdTemp_0; ///< Signal processor adc0 temperature
int8_t spAdTemp_1; ///< Signal processor adc1 temperature
int8_t spFpgaTemp; ///< Signal processor FPGA temperature
// -- Antenna status
uint8_t antVolt; ///< Antenna voltage state indicator
int8_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;
typedef struct
{
// Network log
uint32_t tuNo;
uint8_t slotNo;
uint8_t frameType;
// Payload
uint8_t payload[PAYLOAD_LEN_MAX];
// Time sync info
uint64_t tmStamp;
uint32_t tmDevi;
uint32_t freqDevi;
} SLOTLOG;
typedef struct
{
// Protocol log
// -- System time
uint32_t tmSys;
// -- Physical layer status
uint8_t phySt;
// -- Link layer status
uint64_t tmLocal;
uint16_t beamNo;
uint8_t beamWidth;
// -- Network layer status
uint8_t stage;
uint32_t recvCnt;
uint32_t recvCorrect;
} PRTCLLOG;
typedef struct
{
// Hardware log
// -- Signal processor status
uint16_t spVolt;
uint16_t spTemp;
uint8_t chipSt;
// -- Antenna status
uint8_t antVolt;
uint8_t antTemp;
uint8_t antPll;
uint16_t antMgc;
uint8_t antSt;
} HWSTATE;
typedef struct
{
// Send slot log
SLOTLOG sendLog;
// Receive slot log
SLOTLOG recvLog;
// Protocol log
PRTCLLOG protocolLog;
// Hardware status
HWSTATE hwSate;
} SYSLOG;
/************************** Function Prototypes ******************************/
int32_t SysMonitor_Init(void);
void SysMonitor_Destroy(void);
void SysMonitor_UpdateSysinfo(SYSINFO *info);
void SysMonitor_UpdateSysinfoRaw(uint8_t *buff);
void SysMonitor_UpdateSysinfo(const SYSINFO *info);
void SysMonitor_GetSysinfo(SYSINFO *info);
void SysMonitor_GetSysinfoRaw(uint8_t *buff);
void SysMonitor_UpdateSendPayloadRaw(uint8_t *buff, size_t len);
void SysMonitor_UpdateRecvPayloadRaw(uint8_t *buff, size_t len);
void SysMonitor_GetSendPayloadRaw(uint8_t *buff, uint32_t *id, size_t len);
void SysMonitor_GetRecvPayloadRaw(uint8_t *buff, uint32_t *id, size_t len);
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_UpdateSendSlotLog(SLOTLOG *log);
void SysMonitor_UpdateRecvSlotLog(SLOTLOG *log);
void SysMonitor_UpdateProtocolLog(PRTCLLOG *log);
void SysMonitor_GetSendSlotLog(SLOTLOG *log);
void SysMonitor_GetRecvSlotLog(SLOTLOG *log);
void SysMonitor_GetProtocolLog(PRTCLLOG *log);
void SysMonitor_GetSendSlotLogRaw(uint8_t *buff);
void SysMonitor_GetRecvSlotLogRaw(uint8_t *buff);
void SysMonitor_GetProtocolLogRaw(uint8_t *buff);
void SysMonitor_UpdateHardwareStatus(HWSTATE *state);
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);
void SysMonitor_GetHardwareStatusRaw(uint8_t *buff);
void SysMonitor_GetSyslog(SYSLOG *log);
void SysMonitor_GetSyslogRaw(uint8_t *buff);
#endif //__SYSTEM_MONITOR_H_
/** @} */
+438 -304
View File
@@ -1,22 +1,22 @@
/*****************************************************************************/
/**
* Description: System bus protocol implementation file.
* @file systembus.c
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief System bus protocol implementation file.
* @version 0.1
* @date 2023-05-06
*
* Date: 2023-05-06 10:13
* Last Edit Time: [2023-05-06 21:45]
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
* [2023-09-13]: Update to 485 protocol-20220816
*
* Copyright(c) 2021 Beijing Institute of Technology.
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/***************************** Include Files *********************************/
/**
* @addtogroup SystemBus
* @{
*/
/***************************** Include Files *********************************/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
@@ -27,10 +27,18 @@
#include "common.h"
#include "error.h"
#include "circ_queue.h"
#include "../system_monitor.h"
/**
* @addtogroup SystemBus_Protocol_Routine
* @{
*/
/************************** Constant Definitions *****************************/
/**
* @name SystemBus_MSG_Constants
* @{
*/
// Common Field
// -- Command word
#define WD_CMD 0x00
@@ -51,25 +59,32 @@
#define WD_ST_RET 0x02
#define ST_RET_OK 0xAA
#define ST_RET_ERROR 0x55
// -- -- Signal processor voltage
#define WD_SP_VOLT 0x03
// -- -- Signal processor temperature
#define WD_SP_TEMP 0x04
// -- -- Signal processor chip status
#define WD_SP_CS 0x05
// -- -- Signal processor antenna voltage
#define WD_ANT_VOLT 0x06
// -- -- Signal processor antenna temperature
#define WD_ANT_TEMP 0x07
#define ST_RET_INFO_LEN 13
// -- -- Signal processor PS voltage
#define WD_SP_FPGA_VOLT 0x03
// -- -- Signal processor PS AUX voltage
#define WD_SP_CLK_STATE 0x04
// -- -- Signal processor DDR voltage
#define WD_SP_AD_LOCK_STATE 0x05
// -- -- Signal processor PL voltage
#define WD_SP_AD_TEMP_0 0x06
// -- -- Signal processor PL AUX voltage
#define WD_SP_AD_TEMP_1 0x07
// -- -- Signal processor Bram voltage
#define WD_SP_FPGA_TEMP 0x08
// -- -- Signal processor antenna voltage status
#define WD_ANT_VOLT 0x09
// -- -- Signal processor antenna RF temperature
#define WD_ANT_RF_TEMP 0x0A
// -- -- Signal processor antenna PLL lock status
#define WD_ANT_PLL 0x08
#define WD_ANT_RF_PLL 0x0B
// -- -- Signal processor antenna MGC
#define WD_ANT_MGC_L 0x09
#define WD_ANT_MGC_H 0x0A
// -- -- Signal processor antenna status
#define WD_ANT_ST 0x0B
// -- -- Dummy must be 0x00
#define WD_ST_DUMMY 0x0C
#define WD_ANT_MGC_0 0x0C
#define WD_ANT_MGC_1 0x0D
// -- -- Reserved
#define WD_ANT_RESERVE 0x0E
// Data Send Test Command
#define CMD_DATA_TEST_A 0xE2
@@ -94,7 +109,8 @@
// -- Request
#define WD_EN_CMD 0x02
#define EN_CMD_ON_HIGH_POWER 0x66
#define EN_CMD_ON_LOW_POWER 0x88
#define EN_CMD_ON_LOW_POWER 0x77
#define EN_CMD_SILENT 0x88
#define WD_MODE_CMD 0x03
#define MODE_CMD_HEAD 0x11
@@ -150,6 +166,17 @@
#define WD_FLJ_RM_TEST 0x02
#define FLJ_RM_TEST_CODE 0x99
// -- Response
#define WD_FLJ_TIME_STAMP 0x02
#define WD_FLJ_TIME_STAMP_LEN 8
#define WD_FLJ_SYSBUS_LOG 0x0A
#define WD_FLJ_SYSBUS_LOG_LEN 14
#define WD_FLJ_LINK_LOG 0x18
#define WD_FLJ_LINK_LOG_LEN 64
#define WD_FLJ_PHY_LOG 0x58
#define WD_FLJ_PHY_LOG_LEN 57
#define WD_FLJ_HARDWARE_ST 0x91
#define WD_FLJ_HARDWARE_ST_LEN 13
#define FLJ_RM_TEST_RESP_LEN 158
// Remote Test LJ
@@ -158,13 +185,28 @@
#define WD_LJ_RM_TEST 0x02
#define LJ_RM_TEST_CODE 0x99
// -- Response
#define LJ_RM_TEST_RESP_LEN 158
#define WD_LJ_TIME_STAMP 0x02
#define WD_LJ_TIME_STAMP_LEN 8
#define WD_LJ_SYSBUS_LOG 0x0A
#define WD_LJ_SYSBUS_LOG_LEN 14
#define WD_LJ_LINK_LOG 0x18
#define WD_LJ_LINK_LOG_LEN 64
#define WD_LJ_PHY_LOG 0x58
#define WD_LJ_PHY_LOG_LEN 57
#define WD_LJ_HARDWARE_ST 0x91
#define WD_LJ_HARDWARE_ST_LEN 13
#define LJ_RM_TEST_RESP_LEN 158
// My Production Type
#define MY_PRD_ID PRD_DL_K
/** @} SystemBus_MSG_Constants*/
/************************** Function Prototypes ******************************/
static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr);
static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg);
static int32_t SystemBus_Echo(SYSBUS *instPtr, SYSBUS_UART_FRAME *frame);
static int32_t SystemBus_GenPollRsp(SYSBUS *instPtr, uint8_t *msg);
static int32_t SystemBus_GenRemoteTestRsp(SYSBUS *instPtr, uint8_t *msg);
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
// TODO: better approach?
@@ -173,13 +215,13 @@
extern L2_INST *linkInstPtr;
extern L2_CONFIG linkConfig;
inline bool SystemBus_IsReqPendding(SYSBUS *instPtr)
inline bool SystemBus_IsReqPending(SYSBUS *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->rxQueue));
}
inline bool SystemBus_IsRsqPendding(SYSBUS *instPtr)
inline bool SystemBus_IsRsqPending(SYSBUS *instPtr)
{
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->txQueue));
@@ -196,58 +238,269 @@ inline bool SystemBus_IsRxBusy(SYSBUS *instPtr)
return SysbusUart_IsRxBusy(instPtr->uartInst);
}
/*****************************************************************************/
/**
* @brief Initialize System Bus instance.
*
* @param InstPtr A double pointer to System Bus instance.
* @param config A pointer to System Bus configurations.
*
* @return None.
*
******************************************************************************/
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config)
* @brief Generate System Bus SelfTest response.
*/
static int32_t SystemBus_GenSelfTestRsp(SYSBUS *instPtr)
{
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
SYSBUS_UART_CONFIG uartConfig;
int32_t Status;
(*instPtr) = malloc(sizeof(SYSBUS));
if ((*instPtr) == NULL)
SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL)
{
return FAILURE;
DBG_ERROR("Failed to allocate memory for SELF TEST Response!\n");
return ENOMEM;
}
(*instPtr)->rxQueue = NULL;
(*instPtr)->txQueue = NULL;
(*instPtr)->uartInst = NULL;
memcpy(&((*instPtr)->config), config, sizeof(SYSBUS_CONFIG));
uartConfig.baseAddr = config->baseAddr;
Status = SysbusUart_Init(&((*instPtr)->uartInst), &uartConfig);
if (Status != SUCCESS)
HWSTATE *hwStatsPtr = &(instPtr->hwState);
sysbusRsp->len = ST_RSP_LEN;
memset(sysbusRsp->data, 0x00, ST_RSP_LEN);
sysbusRsp->data[WD_CMD] = CMD_SELF_TEST;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
SysMonitor_GetHardwareStatus(hwStatsPtr);
if (L2_isStarted(linkInstPtr))
{
Status = ENOMEM;
goto sysbus_init_error;
sysbusRsp->data[WD_ST_RET] = (hwStatsPtr->isSpOk && hwStatsPtr->isAntOk) ? ST_RET_OK : ST_RET_ERROR;
}
if (CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false)
else
{
Status = ENOMEM;
goto sysbus_init_error;
sysbusRsp->data[WD_ST_RET] = (hwStatsPtr->isSpOk) ? ST_RET_OK : ST_RET_ERROR;
}
if (CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false)
{
Status = ENOMEM;
goto sysbus_init_error;
}
(*instPtr)->isRxDone = false; // nothing received.
(*instPtr)->isTxDone = true; // nothing to be sent.
return SUCCESS;
// apply status and omit 2 bytes of overhead.
memcpy(sysbusRsp->data + WD_SP_FPGA_VOLT, &(hwStatsPtr->spFpgaVolt), ST_RET_INFO_LEN);
sysbus_init_error:
free((*instPtr)->uartInst);
free((*instPtr)->txQueue);
free((*instPtr)->rxQueue);
free(*instPtr);
return Status;
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp);
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
return EQUEUE;
}
return SUCCESS;
}
/**
* @brief Apply system configuration
*/
static int32_t SystemBus_SystemConfig(SYSBUS *instPtr, uint8_t *msg)
{
ASSERT(instPtr != NULL);
ASSERT(msg != NULL);
PHY_INST *phyRef = linkInstPtr->config.phyInstPtr;
TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr;
bool reconfig = false;
if (msg[WD_MODE_CMD] == MODE_CMD_HEAD)
{
// head node config
reconfig = (L2_NODE_HEAD != L2_GetNodeType(linkInstPtr));
linkConfig.myType = L2_NODE_HEAD;
linkConfig.myId = 1;
}
else if (msg[WD_MODE_CMD] == MODE_CMD_MEMBER)
{
// member node config
reconfig = (L2_NODE_MEMBER != L2_GetNodeType(linkInstPtr));
linkConfig.myType = L2_NODE_MEMBER;
linkConfig.myId = 2;
}
else
{
// Ignore current command
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
WD_MODE_CMD, msg[WD_MODE_CMD]);
return EPARAM;
}
if (msg[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER)
{
// full power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL);
if (reconfig || !L2_isStarted(linkInstPtr))
{
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
Linklayer_Start(linkInstPtr);
}
else if (msg[WD_EN_CMD] == EN_CMD_ON_LOW_POWER)
{
// low power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW);
if (reconfig || !L2_isStarted(linkInstPtr))
{
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
Linklayer_Start(linkInstPtr);
}
else if (msg[WD_EN_CMD] == EN_CMD_SILENT)
{
// silence config
// TODO: better approach?
Linklayer_Halt(linkInstPtr);
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_STANDBY);
TIME_WORD pullTime = {0, 0};
pullTime.int_part = TimeCtrl_GetIntCnt(tmcRef) + 1;
if (Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL) != SUCCESS)
{
DBG_ERROR("Physical set pull time failed.\n");
}
Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL);
}
else
{
// Ignore current command
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
WD_EN_CMD, msg[WD_EN_CMD]);
return EIGNORE;
}
instPtr->sysbusLog.lastConfig[0] = msg[WD_MODE_CMD];
instPtr->sysbusLog.lastConfig[1] = msg[WD_EN_CMD];
return SUCCESS;
}
/**
* @brief Echo System Bus frame
*/
static int32_t SystemBus_Echo(SYSBUS *instPtr, SYSBUS_UART_FRAME *frame)
{
ASSERT(instPtr != NULL);
ASSERT(frame != NULL);
SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for DATA TEST A Response!\n");
return ENOMEM;
}
sysbusRsp->len = frame->len;
memcpy(sysbusRsp->data, frame->data, sysbusRsp->len);
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp);
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
return EQUEUE;
}
return SUCCESS;
}
/**
* @brief Generate System Bus poll call command response
*/
static int32_t SystemBus_GenPollRsp(SYSBUS *instPtr, uint8_t *msg)
{
ASSERT(instPtr != NULL);
ASSERT(msg != NULL);
size_t dataLen;
uint8_t *payload;
SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for FLJ POLL Response!\n");
return ENOMEM;
}
if (msg[WD_CMD] == CMD_FLJ_POLL)
{
sysbusRsp->len = FLJ_POLL_RESP_LEN;
sysbusRsp->data[WD_CMD] = CMD_FLJ_POLL;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
dataLen = PAYLOAD_LEN_FLJ_RX;
payload = sysbusRsp->data + FLJ_DATA_OFFSET;
}
else if (msg[WD_CMD] == CMD_LJ_POLL)
{
sysbusRsp->len = LJ_POLL_RESP_LEN;
sysbusRsp->data[WD_CMD] = CMD_LJ_POLL;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
dataLen = PAYLOAD_LEN_LJ_RX;
payload = sysbusRsp->data + LJ_DATA_OFFSET;
}
else
{
DBG_ERROR("Unexpected command 0x%02X.\n", msg[WD_CMD]);
free(sysbusRsp);
return EUNEXP;
}
uint32_t dataId;
SysMonitor_GetRecvPayload(payload, &dataId, dataLen); // omit control info
if (dataId == DATA_ID_NONE)
{
free(sysbusRsp);
DBG_WARNING("SystemBus::no RX data!\n");
return SUCCESS;
}
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
return EQUEUE;
}
instPtr->sysbusLog.pollCnt++;
return SUCCESS;
}
/**
* @brief Generate System Bus remote test command response
*/
static int32_t SystemBus_GenRemoteTestRsp(SYSBUS *instPtr, uint8_t *msg)
{
ASSERT(instPtr != NULL);
ASSERT(msg != NULL);
SYSBUS_UART_FRAME *sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL)
{
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
return ENOMEM;
}
TIME_WORD tmWord;
uint64_t time;
TimeCtrl_GetCurrentTime(linkInstPtr->config.tmcInstPtr, &tmWord);
time = (uint64_t)tmWord.int_part * TIME_FRAC_MAX + tmWord.frac_part;
if (msg[WD_CMD] == CMD_FLJ_RM_TEST)
{
sysbusRsp->len = FLJ_RM_TEST_RESP_LEN;
memset(sysbusRsp->data, 0x00, FLJ_RM_TEST_RESP_LEN);
sysbusRsp->data[WD_CMD] = CMD_FLJ_RM_TEST;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
memcpy(sysbusRsp->data + WD_FLJ_TIME_STAMP, &time, WD_FLJ_TIME_STAMP_LEN);
SysMonitor_GetLinklayerLog(&(instPtr->linkLog));
SysMonitor_GetPhysicalLayerLog(&(instPtr->phyLog));
SysMonitor_GetHardwareStatus(&(instPtr->hwState));
memcpy(sysbusRsp->data + WD_FLJ_SYSBUS_LOG, &(instPtr->sysbusLog), WD_FLJ_SYSBUS_LOG_LEN);
memcpy(sysbusRsp->data + WD_FLJ_LINK_LOG, &(instPtr->linkLog), WD_FLJ_LINK_LOG_LEN);
memcpy(sysbusRsp->data + WD_FLJ_PHY_LOG, &(instPtr->phyLog), WD_FLJ_PHY_LOG_LEN);
memcpy(sysbusRsp->data + WD_FLJ_HARDWARE_ST, &(instPtr->hwState.spFpgaVolt), WD_FLJ_HARDWARE_ST_LEN);
}
else if (msg[WD_CMD] == CMD_LJ_RM_TEST)
{
sysbusRsp->len = LJ_RM_TEST_RESP_LEN;
sysbusRsp->data[WD_CMD] = CMD_LJ_RM_TEST;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
memcpy(sysbusRsp->data + WD_LJ_TIME_STAMP, &time, WD_LJ_TIME_STAMP_LEN);
SysMonitor_GetLinklayerLog(&(instPtr->linkLog));
SysMonitor_GetPhysicalLayerLog(&(instPtr->phyLog));
SysMonitor_GetHardwareStatus(&(instPtr->hwState));
memcpy(sysbusRsp->data + WD_LJ_SYSBUS_LOG, &(instPtr->sysbusLog), WD_LJ_SYSBUS_LOG_LEN);
memcpy(sysbusRsp->data + WD_LJ_LINK_LOG, &(instPtr->linkLog), WD_LJ_LINK_LOG_LEN);
memcpy(sysbusRsp->data + WD_LJ_PHY_LOG, &(instPtr->phyLog), WD_LJ_PHY_LOG_LEN);
memcpy(sysbusRsp->data + WD_LJ_HARDWARE_ST, &(instPtr->hwState.spFpgaVolt), WD_LJ_HARDWARE_ST_LEN);
}
else
{
DBG_ERROR("Unexpected command 0x%02X.\n", msg[WD_CMD]);
free(sysbusRsp);
return EUNEXP;
}
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
return EQUEUE;
}
instPtr->sysbusLog.remoteCnt++;
return SUCCESS;
}
/*****************************************************************************/
@@ -264,300 +517,106 @@ int32_t SystemBus_HandleCmd(SYSBUS *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
SYSBUS_UART_FRAME *sysbusReq, *sysbusRsp;
uint8_t *data;
SYSBUS_UART_FRAME *sysbusReq;
uint8_t *msg;
if (CircQueuePop(instPtr->rxQueue, (void **)(&sysbusReq)) == false)
{
DBG_WARNING("SystemBus::Nothing to be handled.\n");
return EIGNORE;
}
data = sysbusReq->data;
if (data[WD_PRD] != MY_PRD_ID && data[WD_PRD] != PRD_ALL)
msg = sysbusReq->data;
if (msg[WD_PRD] != MY_PRD_ID && msg[WD_PRD] != PRD_ALL)
{
DBG_WARNING("SystemBus::Production code mismatch!\n");
return EIGNORE;
}
switch (data[WD_CMD])
switch (msg[WD_CMD])
{
case CMD_SELF_TEST:
{
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) {
DBG_ERROR("Failed to allocate memory for SELF TEST Response!\n");
Status = ENOMEM;
break;
}
sysbusRsp->len = ST_RSP_LEN;
memset(sysbusRsp->data, 0x00, ST_RSP_LEN);
sysbusRsp->data[WD_CMD] = CMD_SELF_TEST;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
// FIXME: run self-test and insert result
sysbusRsp->data[WD_ST_RET] = ST_RET_OK;
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp);
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
Status = SystemBus_GenSelfTestRsp(instPtr);
break;
}
case CMD_DATA_TEST_A:
{
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) {
DBG_ERROR("Failed to allocate memory for DATA TEST A Response!\n");
Status = ENOMEM;
break;
}
sysbusRsp->len = DATA_TEST_RSP_A_LEN;
memcpy(sysbusRsp->data, sysbusReq->data, DATA_TEST_RSP_A_LEN);
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp);
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
break;
}
case CMD_DATA_TEST_B:
{
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) {
DBG_ERROR("Failed to allocate memory for DATA TEST B Response!\n");
Status = ENOMEM;
break;
}
sysbusRsp->len = DATA_TEST_RSP_B_LEN;
memcpy(sysbusRsp->data, sysbusReq->data, DATA_TEST_RSP_B_LEN);
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp);
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
Status = SystemBus_Echo(instPtr, sysbusReq);
break;
}
case CMD_CONFIG:
{
PHY_INST *phyRef = linkInstPtr->config.phyInstPtr;
TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr;
if (data[WD_MODE_CMD] == MODE_CMD_HEAD
&& L2_GetNodeType(linkInstPtr) != L2_NODE_HEAD)
{
// head node config
linkConfig.myType = L2_NODE_HEAD;
linkConfig.myId = 1;
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
else if (data[WD_MODE_CMD] == MODE_CMD_MEMBER
&& L2_GetNodeType(linkInstPtr) != L2_NODE_MEMBER)
{
// member node config
linkConfig.myType = L2_NODE_MEMBER;
linkConfig.myId = 2;
Linklayer_Reconfig(linkInstPtr, &linkConfig);
}
else
{
// FIXME: to confirm
// Halt linklayer
Linklayer_Halt(linkInstPtr);
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
WD_MODE_CMD, data[WD_MODE_CMD]);
Status = EPARAM;
break;
}
if(data[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER)
{
// high power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_HIGH_POWER);
}
else if(data[WD_EN_CMD] == EN_CMD_ON_LOW_POWER)
{
// low power config
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_LOW_POWER);
}
else
{
// silence config
// FIXME: confirm
// TODO: better approach?
Linklayer_Halt(linkInstPtr);
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_SILENT);
TIME_WORD pullTime = {0, 0};
pullTime.int_part = TimeCtrl_GetIntCnt(tmcRef) + 1;
Status = Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL);
if (Status != SUCCESS)
{
DBG_ERROR("Physical set pull time failed, with error code: %" PRId32 ".\n", Status);
}
Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL);
break;
}
Linklayer_Start(linkInstPtr);
Status = SUCCESS;
Status = SystemBus_SystemConfig(instPtr, msg);
break;
}
case CMD_SYS_INFO:
{
SysMonitor_UpdateSysinfoRaw(data + SYS_INFO_OFFSET);
SysMonitor_UpdateSysinfo((SYSINFO *)(msg + SYS_INFO_OFFSET));
Status = SUCCESS;
break;
}
// TODO
case CMD_FLJ_SEND:
{
SysMonitor_UpdateSendPayloadRaw(data + FLJ_DATA_OFFSET, PAYLOAD_LEN_FLJ_TX); // omit control info
SysMonitor_UpdateSendPayload(msg + FLJ_DATA_OFFSET, PAYLOAD_LEN_FLJ_TX); // omit control info
instPtr->sysbusLog.svcCnt++;
Status = SUCCESS;
break;
}
case CMD_LJ_SEND:
{
SysMonitor_UpdateSendPayloadRaw(data + LJ_DATA_OFFSET, PAYLOAD_LEN_LJ_TX); // omit control info
SysMonitor_UpdateSendPayload(msg + LJ_DATA_OFFSET, PAYLOAD_LEN_LJ_TX); // omit control info
instPtr->sysbusLog.svcCnt++;
Status = SUCCESS;
break;
}
case CMD_FLJ_POLL:
{
if (data[WD_FLJ_POLL] != FLJ_POLL_CODE)
if (msg[WD_FLJ_POLL] != FLJ_POLL_CODE)
{
DBG_ERROR("SystemBus::Invalid roll call code!\n");
Status = EIGNORE;
break;
}
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) {
DBG_ERROR("Failed to allocate memory for FLJ POLL Response!\n");
Status = ENOMEM;
break;
}
sysbusRsp->len = FLJ_POLL_RESP_LEN;
sysbusRsp->data[WD_CMD] = CMD_FLJ_POLL;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
uint32_t dataId;
SysMonitor_GetRecvPayloadRaw(sysbusRsp->data + FLJ_DATA_OFFSET, &dataId, PAYLOAD_LEN_FLJ_RX); // omit control info
if (dataId == DATA_ID_NONE)
{
free(sysbusRsp);
DBG_WARNING("SystemBus::no RX data!\n");
Status = SUCCESS;
break;
}
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
Status = SystemBus_GenPollRsp(instPtr, msg);
break;
}
case CMD_LJ_POLL:
{
if (data[WD_LJ_POLL] != LJ_POLL_CODE)
if (msg[WD_LJ_POLL] != LJ_POLL_CODE)
{
DBG_WARNING("SystemBus::Invalid roll call code!\n");
Status = EIGNORE;
break;
}
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) {
DBG_ERROR("Failed to allocate memory for LJ POLL Response!\n");
Status = ENOMEM;
break;
}
sysbusRsp->len = LJ_POLL_RESP_LEN;
sysbusRsp->data[WD_CMD] = CMD_LJ_POLL;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
uint32_t dataId;
SysMonitor_GetRecvPayloadRaw(sysbusRsp->data + LJ_DATA_OFFSET, &dataId, PAYLOAD_LEN_LJ_RX); // omit control info
if (dataId == DATA_ID_NONE)
{
free(sysbusRsp);
DBG_WARNING("SystemBus::no RX data!\n");
Status = SUCCESS;
break;
}
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
{
free(sysbusRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
Status = SystemBus_GenPollRsp(instPtr, msg);
break;
}
case CMD_FLJ_RM_TEST:
{
if (data[WD_FLJ_RM_TEST] != FLJ_RM_TEST_CODE)
if (msg[WD_FLJ_RM_TEST] != FLJ_RM_TEST_CODE)
{
DBG_WARNING("SystemBus::Invalid remote test code!\n");
Status = EIGNORE;
break;
}
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) {
DBG_ERROR("Failed to allocate memory for FLJ REMOTE TEST Response!\n");
Status = ENOMEM;
break;
}
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
sysbusRsp->len = FLJ_RM_TEST_RESP_LEN;
memset(sysbusRsp->data, 0x00, FLJ_RM_TEST_RESP_LEN);
sysbusRsp->data[WD_CMD] = CMD_FLJ_RM_TEST;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
free(sysbusRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
Status = SystemBus_GenRemoteTestRsp(instPtr, msg);
break;
}
case CMD_LJ_RM_TEST:
{
if (data[WD_LJ_RM_TEST] != LJ_RM_TEST_CODE)
if (msg[WD_LJ_RM_TEST] != LJ_RM_TEST_CODE)
{
DBG_WARNING("SystemBus::Invalid remote test code!\n");
Status = EIGNORE;
break;
}
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusRsp == NULL) {
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
Status = ENOMEM;
break;
}
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
sysbusRsp->len = LJ_RM_TEST_RESP_LEN;
memset(sysbusRsp->data, 0x00, LJ_RM_TEST_RESP_LEN);
sysbusRsp->data[WD_CMD] = CMD_LJ_RM_TEST;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
free(sysbusRsp);
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
Status = SystemBus_GenRemoteTestRsp(instPtr, msg);
break;
}
default:
{
DBG_ERROR("SystemBus::Unknown command code!\n");
Status = FAILURE;
break;
}
}
@@ -590,6 +649,82 @@ int32_t SystemBus_MakeResp(SYSBUS *instPtr)
return Status;
}
/** @} */
/*****************************************************************************/
/**
* @brief Initialize System Bus instance.
*
* @param InstPtr A double pointer to System Bus instance.
* @param config A pointer to System Bus configurations.
*
* @return Error code.
*
******************************************************************************/
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config)
{
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
SYSBUS_UART_CONFIG uartConfig;
int32_t Status;
(*instPtr) = malloc(sizeof(SYSBUS));
if ((*instPtr) == NULL)
{
return ENOMEM;
}
(*instPtr)->rxQueue = NULL;
(*instPtr)->txQueue = NULL;
(*instPtr)->uartInst = NULL;
memcpy(&((*instPtr)->config), config, sizeof(SYSBUS_CONFIG));
memset(&((*instPtr)->sysbusLog), 0x00, sizeof(SYSBUSLOG));
memset(&((*instPtr)->linkLog), 0x00, sizeof(LINKLOG));
memset(&((*instPtr)->phyLog), 0x00, sizeof(PHYLOG));
memset(&((*instPtr)->hwState), 0x00, sizeof(HWSTATE));
uartConfig.baseAddr = config->baseAddr;
Status = SysbusUart_Init(&((*instPtr)->uartInst), &uartConfig);
if (Status != SUCCESS)
{
SystemBus_Destroy(*instPtr);
return ENOMEM;
}
if (CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false)
{
SystemBus_Destroy(*instPtr);
return ENOMEM;
}
if (CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false)
{
SystemBus_Destroy(*instPtr);
return ENOMEM;
}
(*instPtr)->isRxDone = false; // nothing received.
(*instPtr)->isTxDone = true; // nothing to be sent.
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Destroy System Bus instance.
*
* @param InstPtr A pointer to System Bus instance.
*
* @return None.
*
******************************************************************************/
void SystemBus_Destroy(SYSBUS *instPtr)
{
if (instPtr == NULL)
{
return;
}
free(instPtr->uartInst);
free(instPtr->txQueue);
free(instPtr->rxQueue);
free(instPtr);
}
/*****************************************************************************/
/**
* @brief This function handles the systembus tx irq events.
@@ -619,10 +754,9 @@ int32_t SystemBus_TxIntrHandler(SYSBUS *instPtr)
int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
SYSBUS_UART_FRAME *sysbusReq;
instPtr->isRxDone = true; // whether reception successes or not, receiving procedure ended.
sysbusReq = malloc(sizeof(SYSBUS_UART_FRAME));
int32_t Status;
SYSBUS_UART_FRAME *sysbusReq = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusReq == NULL)
{
return ENOMEM;
@@ -630,17 +764,17 @@ int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr)
Status = SysbusUart_Recv(instPtr->uartInst, sysbusReq);
if (Status != SUCCESS)
{
goto recv_error;
free(sysbusReq);
return Status;
}
if (CircQueuePush(instPtr->rxQueue, (void *)sysbusReq) == false)
{
DBG_ERROR("SystemBus::RX Queue overflowed!\n");
Status = EQUEUE;
goto recv_error;
free(sysbusReq);
return EQUEUE;
}
instPtr->isRxDone = false; // another reception is undergoing.
return SUCCESS;
recv_error:
free(sysbusReq);
return Status;
}
/** @} SystemBus*/
+46 -23
View File
@@ -1,61 +1,84 @@
/*****************************************************************************/
/**
* Description: System bus protocol head file.
* @file systembus.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief System bus protocol header file.
* @version 0.1
* @date 2023-05-06
*
* Date: 2023-05-06 10:12
* Last Edit Time: [2023-05-06 10:13]
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @defgroup SystemBus
* @{
*/
#ifndef __SYSTEMBUS_H_
#define __SYSTEMBUS_H_
/***************************** Include Files *********************************/
#include "systembus_uart.h" // SystemBus UART driver
#include "circ_queue.h"
#include <stdint.h>
#include <stdbool.h>
#include "systembus_uart.h" // SystemBus UART driver
#include "circ_queue.h"
#include "../system_monitor.h"
/************************** Constant Definitions *****************************/
/************************** Data Type Definitions ****************************/
// Definition of SystemBus instance.
/**
* @struct SYSBUS_CONFIG
* @brief SystemBus Config struct holds SystemBus initialization parameters
*/
typedef struct
{
uintptr_t baseAddr;
uint32_t txQueueMax;
uint32_t rxQueueMax;
uintptr_t baseAddr; ///< base address in memory
uint32_t txQueueMax; ///< maximum tx queue length
uint32_t rxQueueMax; ///< maximum rx queue length
} SYSBUS_CONFIG;
/**
* @struct SYSBUS
* @brief SystemBus Instance struct
*/
typedef struct
{
SYSBUS_CONFIG config;
SYSBUS_UART *uartInst;
CIRC_QUEUE *txQueue;
CIRC_QUEUE *rxQueue;
bool isRxDone;
bool isTxDone;
SYSBUS_CONFIG config; ///< SystemBus initialization parameters
SYSBUSLOG sysbusLog; ///< SystemBus log
LINKLOG linkLog; ///< Link layer log
PHYLOG phyLog; ///< Physical layer log
HWSTATE hwState; ///< Hardware status
SYSBUS_UART *uartInst; ///< physical uart controller instance
CIRC_QUEUE *txQueue; ///< tx queue
CIRC_QUEUE *rxQueue; ///< rx queue
bool isTxDone; ///< tx done indicator
bool isRxDone; ///< rx done indicator
} SYSBUS;
/************************** Function Prototypes ******************************/
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config);
void SystemBus_Destroy(SYSBUS *instPtr);
/**
* @defgroup SystemBus_Protocol_Routine
* @{
*/
int32_t SystemBus_HandleCmd(SYSBUS *instPtr);
int32_t SystemBus_MakeResp(SYSBUS *instPtr);
/** @} */
int32_t SystemBus_TxIntrHandler(SYSBUS *instPtr);
int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr);
bool SystemBus_IsReqPendding(SYSBUS *instPtr);
bool SystemBus_IsRsqPendding(SYSBUS *instPtr);
bool SystemBus_IsReqPending(SYSBUS *instPtr);
bool SystemBus_IsRsqPending(SYSBUS *instPtr);
bool SystemBus_IsTxBusy(SYSBUS *instPtr);
bool SystemBus_IsRxBusy(SYSBUS *instPtr);
#endif //__SYSTEMBUS_H_
/** @} SystemBus*/
+31 -14
View File
@@ -1,18 +1,27 @@
/*****************************************************************************/
/**
* Description: System bus uart driver implementation file.
* @file systembus_uart.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief System bus uart driver implementation file.
* @version 0.1
* @date 2023-05-06
*
* Date: 2023-05-06 10:59
* LastEditTime: 2023-05-06 21:56
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/***************************** Include Files *******************************/
/**
* @addtogroup SystemBus
* @{
*/
/**
* @addtogroup SystemBus_UART
* @{
*/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
@@ -20,6 +29,10 @@
#include "systembus_uart.h"
#include "common.h"
/**
* @name SystemBus_UART_Driver_Constants
* @{
*/
// Control and status register
#define MODULE_VERSION 0
#define UART_STATUS 4
@@ -30,9 +43,9 @@
#define UART_STATUS_TX_BUSY 0x00010000
#define UART_STATUS_RX_BUSY 0x01000000
// Data buffer register
#define UART_TXBUFF_LOW 1024
#define UART_TXBUFF_OFFSET 1024
#define UART_TXBUFF_MAX 1024
#define UART_RXBUFF_LOW 2048
#define UART_RXBUFF_OFFSET 2048
#define UART_RXBUFF_MAX 1024
// Frame Data offsets
@@ -47,7 +60,7 @@
#define FRAME_CHECK_LEN 1 // CheckSum
#define FRAME_INFO_LEN 3 // CheckSum, Dummy and DataLen
#define FRAME_OVERHEAD_LEN 7 // CheckSum, Dummy and DataLen
/*************************** Function Definitions ****************************/
/** @} SystemBus_UART_Driver_Constants*/
/*****************************************************************************/
/**
@@ -133,7 +146,7 @@ int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
free(sendBuff);
return FAILURE;
}
memcpy((void *)(instPtr->config.baseAddr + UART_TXBUFF_LOW), sendBuff, (sendLen + sizeof(uint32_t) - 1) / sizeof(uint32_t) * sizeof(uint32_t));
memcpy((void *)(instPtr->config.baseAddr + UART_TXBUFF_OFFSET), sendBuff, (sendLen + sizeof(uint32_t) - 1) / sizeof(uint32_t) * sizeof(uint32_t));
free(sendBuff);
// Start Sending
SYSTEMBUS_UART_mWriteReg(instPtr->config.baseAddr, UART_SEND_CMD, sendLen);
@@ -169,7 +182,7 @@ int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame)
{
return ENOMEM;
}
memcpy(dBuff, (void *)(instPtr->config.baseAddr + UART_RXBUFF_LOW), sizeof(uint32_t) * dWLen);
memcpy(dBuff, (void *)(instPtr->config.baseAddr + UART_RXBUFF_OFFSET), sizeof(uint32_t) * dWLen);
plBuff = dBuff + FRAME_HEAD_LEN;
checkSumCal = 0;
checkSum = plBuff[dLen + FRAME_DUMMY_LEN];
@@ -246,3 +259,7 @@ bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr)
return false;
}
}
/** @} SystemBus_UART*/
/** @} SystemBus*/
+33 -10
View File
@@ -1,17 +1,25 @@
/*****************************************************************************/
/**
* Description: System bus uart driver implementation file.
* @file systembus_uart.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief System bus uart driver header file.
* @version 0.1
* @date 2023-05-06
*
* Date: 2023-05-06 10:59
* LastEditTime: 2023-05-06 21:48
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup SystemBus
* @{
*/
/**
* @defgroup SystemBus_UART
* @{
*/
#ifndef SYSTEMBUS_UART_H
#define SYSTEMBUS_UART_H
@@ -61,22 +69,33 @@
IO_In32((baseAddr) + (offset))
/************************** Data Type Definitions ****************************/
/**
* @struct SYSBUS_UART_CONFIG
* @brief SystemBus UART driver initialization parameters
*/
typedef struct
{
uintptr_t baseAddr;
} SYSBUS_UART_CONFIG;
/**
* @struct SYSBUS_UART
* @brief SystemBus UART driver instance
*/
typedef struct
{
SYSBUS_UART_CONFIG config;
} SYSBUS_UART;
/**
* @struct SYSBUS_UART_FRAME
* @brief SystemBus UART frame definition
*/
typedef struct
{
uint8_t len;
uint16_t len;
uint8_t checkSum;
uint8_t isValid;
uint8_t dummy;
uint8_t data[256];
} SYSBUS_UART_FRAME;
@@ -97,3 +116,7 @@ bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr);
bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr);
#endif // SYSTEMBUS_UART_H
/** @} SystemBus_UART*/
/** @} SystemBus*/
+22 -12
View File
@@ -1,20 +1,21 @@
/*****************************************************************************/
/**
* Description: Time sync implementation file.
*
* Author: Author's name
* Date: 2023-12-20 16:32
* LastEditors: FanHao
* LastEditTime: 2023-12-22 20:43
* Revisions: Rev 0.0
* History:
* [2023-12-20]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @file time_ctrl.c
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Time sync controller driver implementation file.
* @version 0.0
* @date 2023-12-20
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @addtogroup TimeController_Driver
* @{
*/
/***************************** Include Files *********************************/
#include <string.h>
#include "time_ctrl.h"
@@ -23,6 +24,10 @@
#include "util.h"
/************************** Constant Definitions *****************************/
/**
* @name TimeController_REG_Constants
* @{
*/
#define VERSION_REG 0x00000004
#define TIME_INT_REG 0x00000008
#define TIME_FRAC_REG 0x0000000C
@@ -36,6 +41,9 @@
#define CNTSTEP_OPT 0x0000002c
#define TM_RESET_CODE 0x5253542E
/** @} TimeController_REG_Constants*/
/***************** Macros (Inline Functions) Definitions *********************/
#define TMC_Read(instPtr, addr) IO_In32(instPtr->config.baseAddr + addr)
#define TMC_Write(instPtr, addr, value) IO_Out32(instPtr->config.baseAddr + addr, value)
@@ -296,3 +304,5 @@ void TimeCtrl_CalculateTimeGap(const TIME_WORD *a, const TIME_WORD *b, TIME_WORD
gap->frac_part = (TIME_FRAC)(timeDiff % TIME_FRAC_MAX);
gap->frac_part = (TIME_INT)(timeDiff / TIME_FRAC_MAX);
}
/** @} TimeController_Driver*/
+35 -18
View File
@@ -1,19 +1,20 @@
/*****************************************************************************/
/**
* Description: A simplified version of timesync for datalink 814 (Dijian)
*
* Date: 2023-12-20-04 16:32
* LastEditors: Fan Hao
* LastEditTime: 2023-12-20 16:32
* Revisions: Rev 0.0
* History:
* [2023-12-20]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
* @file time_ctrl.h
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Time sync controller driver header file.
* @version 0.0
* @date 2023-12-20
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/**
* @defgroup TimeController_Driver
* @{
*/
#ifndef TIME_CTRL_H_
#define TIME_CTRL_H_
@@ -23,30 +24,44 @@
#define TIME_FRAC_MAX 500000 // how many 10ns in a 5ms
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/**
* @enum TIMECTRL_ADJ_TYPE
* @brief defines the time adjustment methods
*/
typedef enum
{
TM_ADJ_NONE = 0,
TM_ADJ_ADD = 1,
TM_ADJ_SET = 2
TM_ADJ_NONE = 0, ///< none
TM_ADJ_ADD = 1, ///< adjust time by add
TM_ADJ_SET = 2 ///< adjust time by set
} TIMECTRL_ADJ_TYPE;
typedef uint32_t TIME_FRAC;
typedef uint32_t TIME_INT;
/**
* @struct TIME_WORD
* @brief Time controller time word
*/
typedef struct
{
/* 5ms each LSB */
TIME_INT int_part;
/* 10ns each LSB */
TIME_FRAC frac_part;
TIME_INT int_part; ///< 5ms each LSB
TIME_FRAC frac_part; ///< 10ns each LSB
} TIME_WORD;
/**
* @struct TMC_CONFIG
* @brief TmcConfig holds the initialization parameters of time controller
*/
typedef struct
{
uintptr_t baseAddr;
uint32_t reset; // time for reset (unit: us)
} TMC_CONFIG;
/**
* @struct TMC_INST
* @brief An instance struct of time controller
*/
typedef struct
{
TMC_CONFIG config;
@@ -72,3 +87,5 @@ void TimeCtrl_TimeAdjust(TMC_INST *instPtr, const TIME_WORD *tmWord, TIMECTRL_AD
void TimeCtrl_CalculateTimeGap(const TIME_WORD *a, const TIME_WORD *b, TIME_WORD *gap);
#endif /* TIME_SYNC_H_ */
/** @} */
+26 -35
View File
@@ -1,34 +1,25 @@
/*****************************************************************************/
/**
* Description: A simple circular FIFO bounded queue
* @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
*
* Author: Fan Hao
* Date: 2023-02-23 10:29
* LastEditors: Fan Hao
* LastEditTime: 2023-02-23 13:18
* Revisions: Rev 0.0
* History:
* [2023-02-23]: Initial Version.
*
* Copyright(c) 2023 Beijing Institute of Technology.
* Lab of Communication and Networking
* NOTE: Forked from https://github.com/chrismerck/rpa_queue.git
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
/**
* @addtogroup CircularQueue
* @{
*/
#include "circ_queue.h"
#include "common.h"
#include <stdio.h>
@@ -56,14 +47,14 @@ void CircQueueFree(CIRC_QUEUE *queue)
}
/**
* Initialize the CIRC_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)
if (queue == NULL)
{
return false;
}
@@ -74,20 +65,18 @@ bool CircQueueCreate(CIRC_QUEUE **q, uint32_t queueCapacity)
queue->data = malloc(queueCapacity * sizeof(void *));
if (queue->data == NULL)
{
goto error;
free(queue);
return false;
}
queue->bounds = queueCapacity;
queue->nelts = 0;
queue->in = 0;
queue->out = 0;
return true;
error:
free(queue);
return false;
}
/**
* Push new data onto the queue.
* @brief Push new data onto the queue.
*/
bool CircQueuePush(CIRC_QUEUE *queue, void *data)
{
@@ -110,7 +99,7 @@ bool CircQueuePush(CIRC_QUEUE *queue, void *data)
}
/**
* Return current number of element in queue.
* @brief Return current number of element in queue.
*/
inline uint32_t CircQueueSize(CIRC_QUEUE *queue)
{
@@ -118,7 +107,7 @@ inline uint32_t CircQueueSize(CIRC_QUEUE *queue)
}
/**
* Retrieves the next item from the queue.
* @brief Retrieves the next item from the queue.
*/
bool CircQueuePop(CIRC_QUEUE *queue, void **data)
{
@@ -139,3 +128,5 @@ bool CircQueuePop(CIRC_QUEUE *queue, void **data)
}
return true;
}
/** @} CircularQueue*/
/** @} Utility*/
+68 -57
View File
@@ -1,3 +1,25 @@
/*****************************************************************************/
/**
* @file clist.c
* @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
* @{
*/
/**
* @addtogroup cList
* @{
*/
#ifndef LIST_MALLOC
#define LIST_MALLOC malloc
#endif
@@ -6,19 +28,12 @@
#define LIST_FREE free
#endif
//
// list.c
//
// Copyright (c) 2010 TJ Holowaychuk <[email protected]>
//
#include <stdint.h>
#include "clist.h"
/*
* Allocates a new clist_node_t. NULL on failure.
/**
* @brief a new clist_node_t. NULL on failure.
*/
clist_node_t *
clist_node_new(void *val)
{
@@ -31,10 +46,9 @@ clist_node_new(void *val)
return self;
}
/*
* Allocate a new clist_t. NULL on failure.
/**
* @brief Allocate a new clist_t. NULL on failure.
*/
clist_t *
clist_new(void)
{
@@ -49,11 +63,10 @@ clist_new(void)
return self;
}
/*
* Remove all the node in list.
* @self: Pointer to the list
/**
* @brief Remove all the node in list.
* @param self: Pointer to the list
*/
void clist_clear(clist_t *self)
{
clist_node_t *next;
@@ -71,24 +84,21 @@ void clist_clear(clist_t *self)
self->head = NULL;
}
/*
* Free the list.
* @self: Pointer to the list
/**
* @brief Free the list.
* @param self: Pointer to the list
*/
void clist_destroy(clist_t *self)
{
clist_clear(self);
LIST_FREE(self);
}
/*
* Append the given node to the list
* and return the node, NULL on failure.
* @self: Pointer to the list for popping node
* @node: the node to push
/**
* @brief Append the given node to the list and return the node, NULL on failure.
* @param self: Pointer to the list for popping node
* @param node: the node to push
*/
clist_node_t *
clist_rpush(clist_t *self, clist_node_t *node)
{
@@ -112,9 +122,9 @@ clist_rpush(clist_t *self, clist_node_t *node)
return node;
}
/*
* Return / detach the last node in the list, or NULL.
* @self: Pointer to the list for popping node
/**
* @brief Return / detach the last node in the list, or NULL.
* @param self: Pointer to the list for popping node
*/
clist_node_t *
@@ -138,9 +148,9 @@ clist_rpop(clist_t *self)
return node;
}
/*
* Return / detach the first node in the list, or NULL.
* @self: Pointer to the list for popping node
/**
* @brief Return / detach the first node in the list, or NULL.
* @param self: Pointer to the list for popping node
*/
clist_node_t *
@@ -164,11 +174,10 @@ clist_lpop(clist_t *self)
return node;
}
/*
* Prepend the given node to the list
* and return the node, NULL on failure.
* @self: Pointer to the list for pushing node
* @node: the node to push
/**
* @brief Prepend the given node to the list and return the node, NULL on failure.
* @param self: Pointer to the list for pushing node
* @param node: the node to push
*/
clist_node_t *
@@ -194,10 +203,10 @@ clist_lpush(clist_t *self, clist_node_t *node)
return node;
}
/*
* Return the node associated to val or NULL.
* @self: Pointer to the list for finding given value
* @val: Value to find
/**
* @brief Return the node associated to val or NULL.
* @param self: Pointer to the list for finding given value
* @param val: Value to find
*/
clist_node_t *
@@ -230,10 +239,10 @@ clist_find(clist_t *self, void *val)
return NULL;
}
/*
* Return the node at the given index or NULL.
* @self: Pointer to the list for finding given index
* @index: the index of node in the list
/**
* @brief Return the node at the given index or NULL.
* @param self: Pointer to the list for finding given index
* @param index: the index of node in the list
*/
clist_node_t *
@@ -260,10 +269,10 @@ clist_at(clist_t *self, int index)
return NULL;
}
/*
* Remove the given node from the list, freeing it and it's value.
* @self: Pointer to the list to delete a node
* @node: Pointer the node to be deleted
/**
* @brief Remove the given node from the list, freeing it and it's value.
* @param self: Pointer to the list to delete a node
* @param node: Pointer the node to be deleted
*/
void clist_remove(clist_t *self, clist_node_t *node)
@@ -283,8 +292,8 @@ void clist_remove(clist_t *self, clist_node_t *node)
--self->len;
}
/*
* Allocate a new clist_iterator_t. NULL on failure.
/**
* @brief Allocate a new clist_iterator_t. NULL on failure.\n
* Accepts a direction, which may be LIST_HEAD or LIST_TAIL.
*/
@@ -297,8 +306,8 @@ clist_iterator_new(clist_t *list, clist_direction_t direction)
return clist_iterator_new_from_node(node, direction);
}
/*
* Allocate a new clist_iterator_t with the given start
/**
* @brief Allocate a new clist_iterator_t with the given start
* node. NULL on failure.
*/
@@ -313,8 +322,8 @@ clist_iterator_new_from_node(clist_node_t *node, clist_direction_t direction)
return self;
}
/*
* Return the next clist_node_t or NULL when no more
/**
* @brief Return the next clist_node_t or NULL when no more
* nodes remain in the list.
*/
@@ -331,8 +340,8 @@ clist_iterator_next(clist_iterator_t *self)
return curr;
}
/*
* Free the list iterator.
/**
* @brief Free the list iterator.
*/
void clist_iterator_destroy(clist_iterator_t *self)
@@ -340,3 +349,5 @@ void clist_iterator_destroy(clist_iterator_t *self)
LIST_FREE(self);
self = NULL;
}
/** @} cList*/
/** @} Utility*/
+7 -2
View File
@@ -10,11 +10,14 @@
* [2022-07-16]: New branch for Dijian.
* [2021-11-16]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Copyright(c) 2024 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/**
* @addtogroup COMMON_MACRO
* @{
*/
/***************************** Include Files *********************************/
#include "common.h"
#include "error.h"
@@ -44,3 +47,5 @@ void AppAssert(const char *file, int line)
while (1)
;
}
/** @} */
+7 -2
View File
@@ -11,11 +11,14 @@
* [2022-07-17]: Add CRC16_0x8005 CRC8_0x31.
* [2022-01-06]: Initial verion (Basic CRC-16).
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Copyright(c) 2024 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
#include "util.h"
#include "error.h"
@@ -437,3 +440,5 @@ bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_
return false;
}
}
/** @}*/
+56 -21
View File
@@ -1,15 +1,30 @@
/******************************************************************************/
/*****************************************************************************/
/**
* @file util.c
* @author FanHao (hao_fan_bit_ee@163.com)
* @brief Utility functions implementation file
* @version 0.0
* @date 2023-05-06
*
* @copyright Copyright(c) 2024 Beijing Institute of Technology.\n
* Lab of Communication and Network
*
******************************************************************************/
/***************************** Include Files **********************************/
/******************************************************************************/
/**
* @addtogroup Utility
* @{
*/
#include <string.h>
#include <stdlib.h>
// #include <arm_acle.h>
#include "util.h"
#include "error.h"
/******************************************************************************/
/************************** Functions Implementation **************************/
/******************************************************************************/
#ifdef __BITSWAP_TABLE
static uint8_t byte_flipLR[256] =
{
@@ -48,17 +63,26 @@ static uint8_t byte_flipLR[256] =
};
#endif
/**
* @brief Write a 32bit word to specific memory address
*/
inline void IO_Out32(uintptr_t addr, uint32_t value)
{
volatile uint32_t *localAddr = (volatile uint32_t *)addr;
*localAddr = value;
}
/**
* @brief Read a 32bit word from specific memory address
*/
inline uint32_t IO_In32(uintptr_t addr)
{
return *(volatile uint32_t *)addr;
}
/**
* @brief Swap a byte word bit-wise
*/
uint8_t byte_bit_swap(uint8_t byte)
{
#ifdef __BITSWAP_TABLE
@@ -68,6 +92,9 @@ uint8_t byte_bit_swap(uint8_t byte)
#endif
}
/**
* @brief Swap 32bit word bit-wise
*/
uint32_t word_bit_swap(uint32_t word)
{
#ifdef __BITSWAP_TABLE
@@ -85,6 +112,9 @@ uint32_t word_bit_swap(uint32_t word)
#endif
}
/**
* @brief Count ones in an 32bit word
*/
uint32_t count_ones(uint32_t word)
{
#ifdef __GNUC__
@@ -101,13 +131,16 @@ uint32_t count_ones(uint32_t word)
#endif
}
/**
* @brief Convert fix ;oint number to float number
*/
double fix2double(int32_t val, uint8_t frac_bits)
{
return (((double)val) / (BIT(frac_bits)));
}
/**
* Find first set bit in word.
* @brief Find first set bit in word.
*/
uint32_t find_first_set_bit(uint32_t word)
{
@@ -136,7 +169,7 @@ uint32_t find_first_set_bit(uint32_t word)
}
/**
* Find last set bit in word.
* @brief Find last set bit in word.
*/
uint32_t find_last_set_bit(uint32_t word)
{
@@ -166,7 +199,7 @@ uint32_t find_last_set_bit(uint32_t word)
}
/**
* Locate the closest element in an array.
* @brief Locate the closest element in an array.
*/
uint32_t find_closest(int32_t val,
const int32_t *array,
@@ -189,7 +222,7 @@ uint32_t find_closest(int32_t val,
}
/**
* Shift the value and apply the specified mask.
* @brief Shift the value and apply the specified mask.
*/
uint32_t field_prep(uint32_t mask, uint32_t val)
{
@@ -197,7 +230,7 @@ uint32_t field_prep(uint32_t mask, uint32_t val)
}
/**
* Get a field specified by a mask from a word.
* @brief Get a field specified by a mask from a word.
*/
uint32_t field_get(uint32_t mask, uint32_t word)
{
@@ -205,7 +238,7 @@ uint32_t field_get(uint32_t mask, uint32_t word)
}
/**
* Log base 2 of the given number.
* @brief Log base 2 of the given number.
*/
int32_t log_base_2(uint32_t x)
{
@@ -213,7 +246,7 @@ int32_t log_base_2(uint32_t x)
}
/**
* Find greatest common divisor of the given two numbers.
* @brief Find greatest common divisor of the given two numbers.
*/
uint32_t greatest_common_divisor(uint32_t a,
uint32_t b)
@@ -232,7 +265,7 @@ uint32_t greatest_common_divisor(uint32_t a,
}
/**
* Calculate best rational approximation for a given fraction.
* @brief Calculate best rational approximation for a given fraction.
*/
void rational_best_approximation(uint32_t given_numerator,
uint32_t given_denominator,
@@ -257,7 +290,7 @@ void rational_best_approximation(uint32_t given_numerator,
}
/**
* Calculate the number of set bits.
* @brief Calculate the number of set bits.
*/
uint32_t hweight8(uint32_t word)
{
@@ -274,7 +307,7 @@ uint32_t hweight8(uint32_t word)
}
/**
* Calculate the quotient and the remainder of an integer division.
* @brief Calculate the quotient and the remainder of an integer division.
*/
uint64_t do_div(uint64_t *n,
uint64_t base)
@@ -288,7 +321,7 @@ uint64_t do_div(uint64_t *n,
}
/**
* Unsigned 64bit divide with 64bit divisor and remainder
* @brief Unsigned 64bit divide with 64bit divisor and remainder
*/
uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
{
@@ -298,7 +331,7 @@ uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor, uint64_t *remainder)
}
/**
* Unsigned 64bit divide with 32bit divisor with remainder
* @brief Unsigned 64bit divide with 32bit divisor with remainder
*/
uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
{
@@ -308,7 +341,7 @@ uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
}
/**
* Signed 64bit divide with 32bit divisor with remainder
* @brief Signed 64bit divide with 32bit divisor with remainder
*/
int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder)
{
@@ -317,7 +350,7 @@ int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder)
}
/**
* Unsigned 64bit divide with 32bit divisor
* @brief Unsigned 64bit divide with 32bit divisor
*/
uint64_t div_u64(uint64_t dividend, uint32_t divisor)
{
@@ -327,7 +360,7 @@ uint64_t div_u64(uint64_t dividend, uint32_t divisor)
}
/**
* Signed 64bit divide with 32bit divisor
* @brief Signed 64bit divide with 32bit divisor
*/
int64_t div_s64(int64_t dividend, int32_t divisor)
{
@@ -336,7 +369,7 @@ int64_t div_s64(int64_t dividend, int32_t divisor)
}
/**
* Converts from string to int32_t
* @brief Converts from string to int32_t
* @param *str
* @return int32_t
*/
@@ -352,7 +385,7 @@ int32_t str_to_int32(const char *str)
}
/**
* Converts from string to uint32_t
* @brief Converts from string to uint32_t
* @param *str
* @return uint32_t
*/
@@ -366,3 +399,5 @@ uint32_t srt_to_uint32(const char *str)
else
return value;
}
/** @} */
@@ -68,7 +68,7 @@ void linklayer_setup(void)
ASSERT_EQUAL(SUCCESS, Status);
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
ASSERT_EQUAL(SUCCESS, Status);
Status = Phy_InstInit(&phyInstPtr, &l1Config);
Status = Phy_Init(&phyInstPtr, &l1Config);
ASSERT_EQUAL(SUCCESS, Status);
// Update l2 config
+31 -4
View File
@@ -1,14 +1,41 @@
#! /bin/sh
# GE Software
GE_TXATT=0
GE_RXATT=25
DST_DIR=`pwd`
PROJECT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cp -rL $PROJECT_DIR/df_datalink_sp/src $DST_DIR/df_datalink_sp
echo "Creating <df_datalink_ge>..."
cp -rL $PROJECT_DIR/df_datalink_ge/src $DST_DIR/df_datalink_ge
sed -i'' -e "s/antConfig->rfTxMgc = 0;/antConfig->rfTxMgc = $GE_TXATT;/g" $DST_DIR/df_datalink_ge/networking/phy_layer/phy_antenna.c
sed -i'' -e "s/antConfig->rcvMgc = 0;/antConfig->rcvMgc = $GE_RXATT;/g" $DST_DIR/df_datalink_ge/networking/phy_layer/phy_antenna.c
cd $DST_DIR/df_datalink_ge/networking/phy_layer
sed -i "s/antConfig->rfTxMgc = 0;/antConfig->rfTxMgc = $GE_TXATT;/g" ./phy_antenna.c
sed -i "s/antConfig->rcvMgc = 0;/antConfig->rcvMgc = $GE_RXATT;/g" ./phy_antenna.c
# SP Software
source $PROJECT_DIR/caldata
for key in ${!calMap[*]};do
projName=df_datalink_$key
id=$(echo "$key" | grep -o -E '[0-9]+')
type=$(echo "$key" | grep -o -E '(LJ)|(JG)')
echo "Creating <$projName>..."
cp -rL $PROJECT_DIR/df_datalink_sp/src $DST_DIR/$projName
# substitute ID
if [ $type == "LJ" ]; then
sed -i'' "s/#define PHY_DEVICE_ID 0/#define PHY_DEVICE_ID (0x$id | 0x80)/g" $DST_DIR/$projName/config/app_config.h
elif [ $type == "JG" ]; then
sed -i'' "s/#define PHY_DEVICE_ID 0/#define PHY_DEVICE_ID (0x$id | 0x00)/g" $DST_DIR/$projName/config/app_config.h
else
echo "Unrecognized node Type [$type] ID [$id]"
exit 1
fi
# substitute table
sed -i'' "/^const uint16_t antCalTable\[L1_FRAME_MAX_HOPS\]\[L1_ANT_NUM_CH\] =/{
:table
N
/\};/!b table
s/=.*\};/=\n\/\/Antenna-$key\n${calMap[$key]}/
}" $DST_DIR/$projName/networking/phy_layer/phy_antenna.c
done