Compare commits

..
111 Commits
Author SHA1 Message Date
Gatsby Van 07795a2b20 add power mode switch 2024-07-05 11:27:08 +08:00
Gatsby Van 21d3baec98 misc update 2024-07-05 11:26:51 +08:00
Gatsby Van ad0d589141 20240429: physical layer update. 2024-04-29 14:20:12 +08:00
Gatsby Van 247700fee2 omit redundant code 2024-01-31 10:00:02 +08:00
Gatsby Van 31ec331464 *bugfix: correct clear routine 2024-01-29 20:40:38 +08:00
Gatsby Van 297cd0d0da update compensation value (using test value 20240125) 2024-01-25 12:14:27 +08:00
Gatsby Van 452df8ad81 rearrange and remove redundant code 2024-01-25 12:13:02 +08:00
Gatsby Van 966148ebef add debug print. 2024-01-23 16:16:14 +08:00
Gatsby Van 693a63a800 add debug print. 2024-01-23 15:40:03 +08:00
Gatsby Van 5745fef452 update method. 2024-01-23 15:29:09 +08:00
Gatsby Van f4af6a1522 Add new frequency estimation. 2024-01-23 15:29:01 +08:00
Gatsby Van 0f5526736d bugfix: net start check should apply at the beginning of linklayer proc. 2024-01-23 15:28:28 +08:00
Gatsby Van 417e566e3d better print 2024-01-23 15:27:42 +08:00
Gatsby Van 12fc651673 update method. 2024-01-23 15:27:30 +08:00
Gatsby Van cb1e368b58 update method. 2024-01-23 15:26:57 +08:00
Gatsby Van c9058b2c63 update method. 2024-01-23 15:26:39 +08:00
Gatsby Van c722ba4277 update method. 2024-01-23 15:26:24 +08:00
Gatsby Van 6167475307 update naming TOR -> tor 2024-01-23 15:25:43 +08:00
Gatsby Van e55c135229 fix typo. 2024-01-22 16:13:12 +08:00
Gatsby Van 29243b9656 bugfix: ambiguous hopNum. 2024-01-22 16:12:57 +08:00
Gatsby Van de3ae1c3bc bugfix: wrong arguments. 2024-01-22 16:12:38 +08:00
Gatsby Van a0874d55c7 fix typo 2024-01-22 16:12:18 +08:00
Gatsby Van 26d22b67fb simplified naming. 2024-01-22 16:12:10 +08:00
Gatsby Van 35df4d059a omit redundant code. 2024-01-22 11:39:46 +08:00
Gatsby Van 3fb8b7622c add comment. 2024-01-22 11:39:35 +08:00
Gatsby Van deb7433735 simplified function signature. 2024-01-21 17:16:12 +08:00
Gatsby Van 9c335b0ff2 simplified function signature. 2024-01-21 17:15:51 +08:00
Gatsby Van b76f7bedb4 split rtt to individual file. 2024-01-21 15:14:15 +08:00
Gatsby Van 2bf10f25b0 add quaternion to node info. enhance code cohesion. 2024-01-21 15:13:59 +08:00
Gatsby Van 3f38659af0 omit redundant code. 2024-01-21 15:13:21 +08:00
Gatsby Van 1e0ad014de correct naming. 2024-01-21 14:44:21 +08:00
Gatsby Van 61a3c49ce8 list -> clist to avoid naming conflict. 2024-01-21 14:43:36 +08:00
Gatsby Van 162e291533 omit redundant code. 2024-01-21 14:42:51 +08:00
Gatsby Van 726d52c674 rename clist. 2024-01-21 13:35:55 +08:00
Gatsby Van 709619d5bf update change log 2024-01-19 17:12:21 +08:00
Gatsby Van c4e29dfe61 remove df_datalink 2024-01-19 17:11:37 +08:00
Gatsby Van c0e5b0d76c remove df_datalink 2024-01-19 17:05:39 +08:00
Gatsby Van 684a27c959 restore adi list. 2024-01-19 17:00:15 +08:00
Gatsby Van 0556fcb52a bugfix: include 2024-01-19 16:55:03 +08:00
Gatsby Van d03e3592c5 update makefile. 2024-01-19 16:54:50 +08:00
Gatsby Van 22f7822499 miscellaneous update, enhance code coherence. 2024-01-19 16:54:28 +08:00
Gatsby Van 789560d1b5 bugfix: memset 2024-01-19 16:52:55 +08:00
Gatsby Van 171b4e2e7c rename antenna.c. 2024-01-19 16:19:08 +08:00
Gatsby Van 890d6dc02f omit redundant code. 2024-01-19 16:18:27 +08:00
Gatsby Van 3c5310ecdb rename phy_ctrlreg. 2024-01-19 16:18:14 +08:00
Gatsby Van f9cb100f38 omit redundant code. 2024-01-19 13:36:43 +08:00
Gatsby Van 6f5a8d0b17 formatted 2024-01-19 12:48:38 +08:00
Gatsby Van 64d02b3a71 adapted to new protocol specification. 2024-01-19 11:49:48 +08:00
Gatsby Van 286787f01c file substitute. 2024-01-19 11:06:07 +08:00
Gatsby Van a3fd398729 bugfix: fix frame type inference. 2024-01-05 16:39:54 +08:00
Gatsby Van 7f852e9ddc update comments. 2024-01-05 16:25:15 +08:00
Gatsby Van aabaaa94c3 fix typo. 2024-01-05 16:14:10 +08:00
Gatsby Van 22a3a7ad57 bugfix: correct the condition of transitioning to seek state. 2024-01-05 16:13:58 +08:00
Gatsby Van 1909df3b9c miscellaneous fix. 2024-01-05 16:12:22 +08:00
Gatsby Van 8b46723c20 add comments. 2023-12-27 19:47:06 +08:00
Gatsby Van 13f07021de miscellaneous fix. 2023-12-27 17:17:22 +08:00
Gatsby Van fbe41ce9a6 bugfix: correct mpc info update. 2023-12-27 17:17:10 +08:00
Gatsby Van 932b4561d5 bugfix: update physical layer compensation value. 2023-12-27 17:16:36 +08:00
Gatsby Van 912b30e457 bugfix: correct scan net restart mechanism. 2023-12-27 17:15:55 +08:00
Gatsby Van 5453b487ff bugfix: correct w2acq frame logging. 2023-12-27 17:15:26 +08:00
Gatsby Van 1e57ca2c1b miscellaneous fix. 2023-12-27 17:14:58 +08:00
Gatsby Van 6bf35c8c5d bugfix: correct coarse frequency formulation. 2023-12-27 15:23:16 +08:00
Gatsby Van 677b8b4af5 formatted. 2023-12-27 14:59:41 +08:00
Gatsby Van fa5ff861d5 formatted. 2023-12-27 14:56:30 +08:00
Gatsby Van cb109ad581 omit redundant code. 2023-12-27 14:54:46 +08:00
Gatsby Van 83e43f791c formatted code. 2023-12-26 22:04:40 +08:00
Gatsby Van 5cb5ffff59 miscellaneous update, omit redundant FIXME flag. 2023-12-26 21:52:01 +08:00
Gatsby Van 10fbdc78a6 add logging module. 2023-12-26 21:51:28 +08:00
Gatsby Van 7071b5bf33 omit blank line. 2023-12-26 21:21:19 +08:00
Gatsby Van 28e4428468 omit redundant code. 2023-12-26 21:20:55 +08:00
Gatsby Van 9dabdf0984 update descriptions. 2023-12-26 21:15:07 +08:00
Gatsby Van 7b3be7bc77 adapted to new phy_ctrl "get time stamp" api 2023-12-26 21:13:22 +08:00
Gatsby Van d6002b961b update "get time stamp" apis. 2023-12-26 21:12:54 +08:00
Gatsby Van 25ac8b0784 miscellaneous update. 2023-12-26 21:09:17 +08:00
Gatsby Van 81a26ea3b3 omit redundant code. 2023-12-26 21:08:55 +08:00
Gatsby Van 5dd9695a77 miscellaneous fix. 2023-12-26 21:07:34 +08:00
Gatsby Van 2588564be2 adapted to pl update (individual time adjustment mode). 2023-12-26 11:06:18 +08:00
Gatsby Van 5c5a50e4ad update time sync api. 2023-12-26 11:04:15 +08:00
Gatsby Van b3451b6c0a adapted to new time sync api. 2023-12-26 11:03:57 +08:00
Gatsby Van f29ffb561d better print. 2023-12-26 11:03:19 +08:00
Gatsby Van 34dcdcd0f6 update time sync api. 2023-12-26 11:03:01 +08:00
Gatsby Van 4760abdb96 update net setup event implementation. 2023-12-26 11:02:48 +08:00
Gatsby Van c98472cad7 bugfix 2023-12-26 11:02:26 +08:00
Gatsby Van f2ce6897d2 better print. 2023-12-26 11:00:21 +08:00
Gatsby Van 6f98baf096 change COUNTE_FRAC_MAX -> TIME_FRAC_MAX 2023-12-25 17:23:06 +08:00
Gatsby Van bac0860b7b update time adjust parameter validation. 2023-12-25 17:22:08 +08:00
Gatsby Van ae9c0d5243 bugfix: correct return condition. 2023-12-25 17:21:05 +08:00
Gatsby Van 222e262194 bugfix: should handle init scan frame as bm frame. 2023-12-25 17:20:14 +08:00
Gatsby Van 383de5a3c9 fix typo 2023-12-24 13:09:31 +08:00
Gatsby Van 7157cf668c update record shift mechanism (more reasonable.) 2023-12-24 13:08:19 +08:00
Gatsby Van 54c20aa46e add method peek data. 2023-12-24 13:07:30 +08:00
Gatsby Van ab9ef5b06c clean up. 2023-12-24 13:06:57 +08:00
Gatsby Van da008809de add physical interrupt. 2023-12-24 13:05:00 +08:00
Gatsby Van eba0147d2f add physical interrupt handler, handle physical layer interrupt and 5ms interrupt independently. 2023-12-24 13:04:46 +08:00
Gatsby Van 2a20921193 better debug print. 2023-12-24 13:03:18 +08:00
Gatsby Van 6ab4293c76 adapted to new list api. 2023-12-23 17:01:58 +08:00
Gatsby Van d746215628 add feature for sorting list. 2023-12-23 17:01:39 +08:00
Gatsby Van 4b79a1436a fix typo. 2023-12-23 13:59:00 +08:00
Gatsby Van 7b1c20e054 bugfix: correct record shit mechanism. 2023-12-23 13:57:44 +08:00
Gatsby Van 5a46a21d4f adapted to new time control api. 2023-12-22 13:20:57 +08:00
Gatsby Van 3b927140bd add rtt test. 2023-12-22 13:20:23 +08:00
Gatsby Van 80562ca54e update comment. 2023-12-22 13:20:07 +08:00
Gatsby Van dc292a8cd3 add time util function. 2023-12-22 13:19:43 +08:00
Gatsby Van 2a17fa9183 bugfix: reveal physical flag directly. 2023-12-22 13:18:38 +08:00
Gatsby Van 633be421b1 better debug print. 2023-12-22 13:14:37 +08:00
Gatsby Van 26a912dcc0 bugfix: correct record shift mechanism. 2023-12-22 13:14:21 +08:00
Gatsby Van 15ed440200 include stdio 2023-12-22 13:13:26 +08:00
Gatsby Van 6aa2f271f5 enhance coherence. 2023-12-22 10:40:55 +08:00
Gatsby Van c5730a7fd5 omit redundant code. 2023-12-22 10:15:33 +08:00
Gatsby Van 96181a0734 better debug print. 2023-12-22 10:15:18 +08:00
Gatsby Van 8a94ffacac adapt to new node list api. 2023-12-22 01:36:13 +08:00
432 changed files with 7392 additions and 107429 deletions
-2
View File
@@ -3,10 +3,8 @@ DIR := $(shell pwd)
compile_test:
cd $(DIR)/datalink814_ge/build && make all
cd $(DIR)/datalink814_sp/build && make all
cd $(DIR)/df_datalink/build && make all
clean:
cd $(DIR)/datalink814_ge/build && make clean
cd $(DIR)/datalink814_sp/build && make clean
cd $(DIR)/df_datalink/build && make clean
.PHONY: clean compile_test
+10
View File
@@ -0,0 +1,10 @@
# Datalink 814 Projects
## Changelog
### 2023-12-21
* Rewrote node list
* Rewrote schedule event pool
* Simplified RTT procedure
* Adapted to new physical layer implementation (by 牛蒙浩 何广源)
+5 -3
View File
@@ -39,7 +39,9 @@
* @return NONE.
*
******************************************************************************/
void AppAssert(const char * file, int line){
DBG_PRINT("in %s #%4d [assert] .\n",file, line);
while(1);
void AppAssert(const char *file, int line)
{
DBG_PRINT("[assert]\tin %s:%4d.\n", file, line);
while (1)
;
}
+30 -22
View File
@@ -21,62 +21,70 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#include "util/util.h"
#include "error.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define __PRINT_BLOCK(block) do {\
block\
} while(0)
#define __PRINT_BLOCK(block) \
do \
{ \
block \
} while (0)
#define ASSERT(exp) ((exp) ? (void)0 : AppAssert(__FILE__, __LINE__))
#define _nop_() __asm__("nop")
#define _nop_() __asm__("nop")
/* Stringify */
#define STR(x) #x
#define STR(x) #x
#define _814_DEBUG_LEVEL 3
// #define _814_DEBUG_LEVEL 3
#if _814_DEBUG_LEVEL > 0
#define DBG_PRINT(...) printf(__VA_ARGS__)
#define DBG_PRINT(...) printf(__VA_ARGS__)
#endif
#if _814_DEBUG_LEVEL >= 1
#define DBG_ERROR(...) __PRINT_BLOCK( \
printf("in"__FILE__" #%4d [error]\t",__LINE__); \
printf(__VA_ARGS__); \
)
printf("[error]\tin "__FILE__ \
":%4d ", \
__LINE__); \
printf(__VA_ARGS__);)
#endif
#if _814_DEBUG_LEVEL >= 2
#define DBG_WARNING(...) __PRINT_BLOCK( \
printf("[warning]\t"); \
printf(__VA_ARGS__); \
)
printf("[warning]\t"); \
printf(__VA_ARGS__);)
#endif
#if _814_DEBUG_LEVEL >= 3
#define DBG_INFO(...) __PRINT_BLOCK( \
printf("[Info]\t"); \
printf(__VA_ARGS__); \
)
printf("[Info]\t"); \
printf(__VA_ARGS__);)
#endif
#ifndef DBG_ERROR
#define DBG_ERROR(...) {}
#define DBG_ERROR(...) \
{ \
}
#endif
#ifndef DBG_WARNING
#define DBG_WARNING(...) {}
#define DBG_WARNING(...) \
{ \
}
#endif
#ifndef DBG_INFO
#define DBG_INFO(...) {}
#define DBG_INFO(...) \
{ \
}
#endif
#ifndef DBG_PRINT
#define DBG_PRINT(...) {}
#define DBG_PRINT(...) \
{ \
}
#endif
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
void AppAssert(const char * file, int line);
void AppAssert(const char *file, int line);
#endif /* __COMMON_H_ */
+1
View File
@@ -59,6 +59,7 @@
#define PHY_DEVICE_ID 0
// Interrupt Configs
#define PHY_INTR_ID XPAR_FABRIC_PHY_IRQ_INTR
#define PERIODIC_5MS_INTR_ID XPAR_FABRIC_PHY_5MS_DELAY_2MS_INTR
#define MPC_RX_DONE_INTR_ID XPAR_FABRIC_MPC_IRQ_INTR
#define MPC_BUFFER_LENGTH (XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_S_AXI_HIGHADDR \
+9 -9
View File
@@ -10,21 +10,21 @@
#ifdef SUCCESS
#undef SUCCESS
#endif
#define SUCCESS 0
#define SUCCESS 0
#ifdef FAILURE
#undef FAILURE
#endif
#define FAILURE -1
#define FAILURE -1
#define EPARAM -2 /*!< Data crc check failed */
#define EPARAM -2 /*!< Data crc check failed */
#define ECRC -3 /*!< Data crc check failed */
#define EDINVAL -4 /*!< Device is invalid (sleep or power off) */
#define EDCONF -5 /*!< Device confugure error */
#define EDINVAL -4 /*!< Device is invalid (sleep or power off) */
#define EDCONF -5 /*!< Device confugure error */
#define ETIMEOUT -6 /*!< Timeout error */
#define EIGNORE -7 /*!< Received an unsupported command, and ignore it */
#define EQUEUE -8 /*!< Queue overflow */
#define EALLOC -9 /*!< Failed to allocate memory */
#define EUNEXP -10 /*!< Encounter an unexpected error */
#define EIGNORE -7 /*!< Received an unsupported command, and ignore it */
#define EQUEUE -8 /*!< Queue overflow */
#define EALLOC -9 /*!< Failed to allocate memory */
#define EUNEXP -10 /*!< Encounter an unexpected error */
// #define IS_ERR_VALUE(x) ((x) != SUCCESS)
+17 -19
View File
@@ -75,11 +75,11 @@ int HARDWARE_initialize()
// /**********************************************************/
// Status = HW_ad9371DynamicCfgInit();
// if (Status != ADIERR_OK){
// xil_printf("HW:: AD9371 dynamic configuration initialization failed!\n");
// printf("HW:: AD9371 dynamic configuration initialization failed!\n");
// return ADIERR_FAILED;
// }
//
// xil_printf("HW:: AD9371 ready to be reconfigured!\n");
// printf("HW:: AD9371 ready to be reconfigured!\n");
//
// // main loop
// while(1);
@@ -97,8 +97,6 @@ int HARDWARE_ad9371Config(void)
uint8_t obsFramerStatus;
uint8_t deframerStatus;
xil_printf("main: Hello\n");
/**********************************************************/
/*********** Initialize Configuration Interface ***********/
/**********************************************************/
@@ -112,7 +110,7 @@ int HARDWARE_ad9371Config(void)
return ADIERR_FAILED;
}
xil_printf("HW:: Initialize configuration interface done!\n");
printf("HW:: Initialize configuration interface done!\n");
/**********************************************************/
/****************** AD9528 Configuration ******************/
@@ -122,14 +120,14 @@ int HARDWARE_ad9371Config(void)
return ADIERR_FAILED;
}
xil_printf("HW:: AD9528 configuration done!\n");
printf("HW:: AD9528 configuration done!\n");
Status = HW_9528GetLockStatus(ad9528Init, &reg508);
if (Status != ADIERR_OK){
return ADIERR_FAILED;
}
xil_printf("HW:: AD9528 REG508: 0x%02x \n",reg508);
printf("HW:: AD9528 REG508: 0x%02x\n",reg508);
/**********************************************************/
/****************** AD9371 Configuration ******************/
@@ -153,7 +151,7 @@ int HARDWARE_ad9371Config(void)
printf("HW:: DeframerStatus = 0x%x\n", deframerStatus);
}
xil_printf("HW:: All configuration done!\n");
printf("HW:: All configuration done!\n");
return ADIERR_OK;
}
@@ -232,13 +230,13 @@ int HW_setupIntrSystem(u16 DeviceId, XScuGic * GicPtr)
*/
CfgPtr = XScuGic_LookupConfig(DeviceId);
if (!CfgPtr) {
xil_printf("No interrupt config found for %d\n", DeviceId);
printf("No interrupt config found for %d\n", DeviceId);
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(GicPtr, CfgPtr, CfgPtr->CpuBaseAddress);
if (Status != XST_SUCCESS) {
xil_printf("No interrupt config found for %d\n", DeviceId);
printf("No interrupt config found for %d\n", DeviceId);
return XST_FAILURE;
}
@@ -810,7 +808,7 @@ int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
*/
if((mykError = MYKONOS_radioOff(mykDevice)) != MYKONOS_ERR_OK)
{
xil_printf("Turn radio off failed!\n\r");
printf("Turn radio off failed!\n\r");
return ADIERR_FAILED;
}
@@ -820,14 +818,14 @@ int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
if((mykError = MYKONOS_setRfPllFrequency(mykDevice, TX_PLL,
freq_Hz)) != MYKONOS_ERR_OK)
{
xil_printf("Set TX PLL failed!\n\r");
printf("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 > ***/
xil_printf("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
printf("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
}
/*
@@ -836,7 +834,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
// {
// xil_printf("Reset external channel FAILED!");
// printf("Reset external channel FAILED!");
// }
/*
@@ -844,7 +842,7 @@ int HW_9371SmallFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
*/
if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK)
{
xil_printf("Turn radio on failed!\n\r");
printf("Turn radio on failed!\n\r");
return ADIERR_FAILED;
}
@@ -854,7 +852,7 @@ 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
// {
// xil_printf("Reenable tracking calibrations FAILED!");
// printf("Reenable tracking calibrations FAILED!");
// }
return ADIERR_OK;
}
@@ -877,7 +875,7 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
*/
if((mykError = MYKONOS_radioOff(mykDevice)) != MYKONOS_ERR_OK)
{
xil_printf("Turn radio off failed!\n\r");
printf("Turn radio off failed!\n\r");
return ADIERR_FAILED;
}
@@ -894,7 +892,7 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
if ((pllLockStatus & 0x07) != 0x07)
{
/*** < Info: Clock, Rx and Tx PLLs not locked > ***/
xil_printf("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
printf("Not all PLLs locked, lock status: 0x%02x\n", pllLockStatus);
}
/*
@@ -957,7 +955,7 @@ int HW_9371LargeFrequencyChange(mykonosDevice_t *mykDevice, uint64_t freq_Hz)
*/
if ((mykError = MYKONOS_radioOn(mykDevice)) != MYKONOS_ERR_OK)
{
xil_printf("Turn radio on failed!\n\r");
printf("Turn radio on failed!\n\r");
return ADIERR_FAILED;
}
+107 -97
View File
@@ -1,18 +1,18 @@
/*****************************************************************************/
/**
* Description: Functions for framing operations.
*
*
* Date: 2022-07-16 14:17
* LastEditors: Fan Hao
* LastEditTime: 2022-07-16 17:11
* Revisions: Rev x.x
* History:
* History:
* [YYYY-MM-DD]: Description of modification.
*
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <stdint.h>
@@ -25,50 +25,42 @@
/************************** Constant Definitions *****************************/
// Definition of each slot content
L2_MSG_TYPE intraBmFrameMsgs[1] = {
L2_MSG_BM
};
L2_MSG_BM};
L2_MSG_TYPE intraW2AcqFrameMsgs[6] = {
L2_MSG_SCAN_INIT,
L2_MSG_SCAN_CONT_1,
L2_MSG_SCAN_CONT_2,
L2_MSG_SCAN_CONT_3,
L2_MSG_SCAN_CONT_4,
L2_MSG_SCAN_CONT_5
};
L2_MSG_SCAN_INIT,
L2_MSG_SCAN_CONT_1,
L2_MSG_SCAN_CONT_2,
L2_MSG_SCAN_CONT_3,
L2_MSG_SCAN_CONT_4,
L2_MSG_SCAN_CONT_5};
L2_MSG_TYPE intraMgmtFrameMsgs[6] = {
L2_MSG_TK_INIT,
L2_MSG_TK_EXTD,
L2_MSG_TK_CONT_1,
L2_MSG_TK_CONT_2,
L2_MSG_TK_CONT_3,
L2_MSG_NQT_INIT
};
L2_MSG_TK_INIT,
L2_MSG_TK_EXTD,
L2_MSG_TK_CONT_1,
L2_MSG_TK_CONT_2,
L2_MSG_TK_CONT_3,
L2_MSG_NQT_INIT};
L2_MSG_TYPE taFrameMsgs[4] = {
L2_MSG_TA_INIT,
L2_MSG_TA_EXTD,
L2_MSG_TA_CONT_1,
L2_MSG_TA_CONT_2
};
L2_MSG_TA_INIT,
L2_MSG_TA_EXTD,
L2_MSG_TA_CONT_1,
L2_MSG_TA_CONT_2};
L2_MSG_TYPE interSvcFrameMsgs[2] = {
L2_MSG_LINK_INIT,
L2_MSG_LINK_CONT_1
};
L2_MSG_LINK_INIT,
L2_MSG_LINK_CONT_1};
L2_MSG_TYPE rttReqFrameMsgs[3] = {
L2_MSG_RTT_REQ_INIT,
L2_MSG_RTT_REQ_EXTD,
L2_MSG_RTT_REQ_CONT
};
L2_MSG_RTT_REQ_INIT,
L2_MSG_RTT_REQ_EXTD,
L2_MSG_RTT_REQ_CONT};
L2_MSG_TYPE rttRspFrameMsgs[3] = {
L2_MSG_RTT_RSP_INIT,
L2_MSG_RTT_RSP_EXTD,
L2_MSG_RTT_RSP_CONT
};
L2_MSG_RTT_RSP_INIT,
L2_MSG_RTT_RSP_EXTD,
L2_MSG_RTT_RSP_CONT};
/*****************************************************************************/
/**
@@ -84,9 +76,10 @@ L2_MSG_TYPE rttRspFrameMsgs[3] = {
* SUCCESS
*
******************************************************************************/
void FrameInsertChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint64_t chunk){
void FrameInsertChunk(BIT_ARRAY *bitarr, uint32_t offset, uint32_t numBit, uint64_t chunk)
{
ASSERT(bitarr != NULL);
ASSERT(bitarr->num_of_bits >= offset+numBit && numBit <= 64);
ASSERT(bitarr->num_of_bits >= offset + numBit && numBit <= 64);
#ifdef CHUNK_FILL_STYLE_XJY
int32_t bitRmn = numBit;
uint64_t dataWr = 0;
@@ -94,12 +87,13 @@ void FrameInsertChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint6
uint32_t byteOff = 0;
uint32_t bitWr = 0;
uint32_t bitWrCnt = 0;
while (bitRmn > 0){
bitOff = offset%8;
byteOff = offset/8;
bitWr = (bitRmn > (8-bitOff)) ? (8-bitOff) : bitRmn;
dataWr = chunk>>(numBit-(bitWr + bitWrCnt));
bit_array_set_wordn(bitarr, byteOff*8 + (8-bitOff-bitWr), dataWr, bitWr);
while (bitRmn > 0)
{
bitOff = offset % 8;
byteOff = offset / 8;
bitWr = (bitRmn > (8 - bitOff)) ? (8 - bitOff) : bitRmn;
dataWr = chunk >> (numBit - (bitWr + bitWrCnt));
bit_array_set_wordn(bitarr, byteOff * 8 + (8 - bitOff - bitWr), dataWr, bitWr);
bitWrCnt += bitWr;
bitRmn -= bitWr;
offset += bitWr;
@@ -123,26 +117,28 @@ void FrameInsertChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint6
* SUCCESS
*
******************************************************************************/
void FrameGetChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint64_t* chunk){
void FrameGetChunk(BIT_ARRAY *bitarr, uint32_t offset, uint32_t numBit, uint64_t *chunk)
{
ASSERT(bitarr != NULL);
ASSERT(bitarr->num_of_bits >= offset+numBit && numBit <= 64);
ASSERT(bitarr->num_of_bits >= offset + numBit && numBit <= 64);
#ifdef CHUNK_FILL_STYLE_XJY
int32_t bitRmn = numBit;
uint64_t dataRd = 0;
uint32_t bitOff = offset%8;
uint32_t byteOff = offset/8;
uint32_t bitRd = (bitRmn > (8-bitOff)) ? (8-bitOff) : bitRmn;
uint32_t bitOff = offset % 8;
uint32_t byteOff = offset / 8;
uint32_t bitRd = (bitRmn > (8 - bitOff)) ? (8 - bitOff) : bitRmn;
uint32_t bitRdCnt = 0;
while (bitRmn > 0){
dataRd |= bit_array_get_wordn(bitarr, byteOff*8 + (8-bitOff-bitRd), bitRd);
while (bitRmn > 0)
{
dataRd |= bit_array_get_wordn(bitarr, byteOff * 8 + (8 - bitOff - bitRd), bitRd);
bitRdCnt += bitRd;
bitRmn -= bitRd;
offset += bitRd;
bitOff = offset%8;
byteOff = offset/8;
bitRd = (bitRmn > (8-bitOff)) ? (8-bitOff) : bitRmn;
dataRd = dataRd<<bitRd;
bitOff = offset % 8;
byteOff = offset / 8;
bitRd = (bitRmn > (8 - bitOff)) ? (8 - bitOff) : bitRmn;
dataRd = dataRd << bitRd;
}
*chunk = dataRd;
return SUCCESS;
@@ -164,25 +160,28 @@ void FrameGetChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint64_t
* SUCCESS
*
******************************************************************************/
static int32_t L2_CrcGen(uint8_t* dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType, uint32_t* crc){
// ASSERT(dataBuff != NULL);
static int32_t L2_CrcGen(uint8_t *dataBuff, uint32_t dataLen, L2_CRC_TYPE crcType, uint32_t *crc)
{
// ASSERT(dataBuff != NULL);
int32_t Status = SUCCESS;
uint32_t crcVal = 0;
switch (crcType){
switch (crcType)
{
case L2_CRC16_1021:
Status = crc16_gen(dataBuff, dataLen, 0x1021, (uint16_t*)&crcVal);
Status = crc16_gen(dataBuff, dataLen, 0x1021, (uint16_t *)&crcVal);
break;
case L2_CRC16_8005:
Status = crc16_gen(dataBuff, dataLen, 0x8005, (uint16_t*)&crcVal);
Status = crc16_gen(dataBuff, dataLen, 0x8005, (uint16_t *)&crcVal);
break;
case L2_CRC8_31:
Status = crc8_gen(dataBuff, dataLen, 0x31, (uint8_t*)&crcVal);
Status = crc8_gen(dataBuff, dataLen, 0x31, (uint8_t *)&crcVal);
break;
default:
Status = EPARAM;
break;
}
if(Status == SUCCESS){
if (Status == SUCCESS)
{
*crc = crcVal;
}
return Status;
@@ -201,24 +200,27 @@ static int32_t L2_CrcGen(uint8_t* dataBuff, uint32_t dataLen, L2_CRC_TYPE crcTyp
* SUCCESS
*
******************************************************************************/
int32_t L2_CrcAppend(uint8_t* dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType){
// ASSERT(dataBuff != NULL);
int32_t L2_CrcAppend(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType)
{
// ASSERT(dataBuff != NULL);
int32_t Status = SUCCESS;
uint32_t crcVal = 0;
uint8_t* crcPtr = dataBuff+crcPos;
Status = L2_CrcGen(dataBuff,dataLen, crcType, &crcVal);
if(Status != SUCCESS){
uint8_t *crcPtr = dataBuff + crcPos;
Status = L2_CrcGen(dataBuff, dataLen, crcType, &crcVal);
if (Status != SUCCESS)
{
return Status;
}
#ifdef CHUNK_FILL_STYLE_XJY
switch (crcType){
switch (crcType)
{
case L2_CRC16_1021:
*crcPtr = (uint8_t)(crcVal>>8);
*(crcPtr+1) = (uint8_t)(crcVal);
*crcPtr = (uint8_t)(crcVal >> 8);
*(crcPtr + 1) = (uint8_t)(crcVal);
break;
case L2_CRC16_8005:
*crcPtr = (uint8_t)(crcVal>>8);
*(crcPtr+1) = (uint8_t)(crcVal);
*crcPtr = (uint8_t)(crcVal >> 8);
*(crcPtr + 1) = (uint8_t)(crcVal);
break;
case L2_CRC8_31:
*crcPtr = (uint8_t)crcVal;
@@ -228,13 +230,14 @@ int32_t L2_CrcAppend(uint8_t* dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CR
break;
}
#else
switch (crcType){
switch (crcType)
{
case L2_CRC16_1021:
*(crcPtr+1) = (uint8_t)(crcVal>>8);
*(crcPtr + 1) = (uint8_t)(crcVal >> 8);
*crcPtr = (uint8_t)(crcVal);
break;
case L2_CRC16_8005:
*(crcPtr+1) = (uint8_t)(crcVal>>8);
*(crcPtr + 1) = (uint8_t)(crcVal >> 8);
*crcPtr = (uint8_t)(crcVal);
break;
case L2_CRC8_31:
@@ -261,26 +264,29 @@ int32_t L2_CrcAppend(uint8_t* dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CR
* SUCCESS
*
******************************************************************************/
bool L2_CrcCheck(uint8_t* dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType){
bool L2_CrcCheck(uint8_t *dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TYPE crcType)
{
ASSERT(dataBuff != NULL);
int32_t Status = SUCCESS;
uint32_t crcVal = 0;
uint32_t crcComp = 0;
uint8_t* crcPtr = dataBuff+crcPos;
Status = L2_CrcGen(dataBuff,dataLen, crcType, &crcVal);
if(Status != SUCCESS){
uint8_t *crcPtr = dataBuff + crcPos;
Status = L2_CrcGen(dataBuff, dataLen, crcType, &crcVal);
if (Status != SUCCESS)
{
return false;
}
#ifdef CHUNK_FILL_STYLE_XJY
switch (crcType){
switch (crcType)
{
case L2_CRC16_1021:
crcComp = ((uint32_t)(*crcPtr)) << 8;
crcComp |= (uint32_t)(*(crcPtr+1));
crcComp |= (uint32_t)(*(crcPtr + 1));
break;
case L2_CRC16_8005:
crcComp = ((uint32_t)(*crcPtr)) << 8;
crcComp |= (uint32_t)(*(crcPtr+1));
crcComp |= (uint32_t)(*(crcPtr + 1));
break;
case L2_CRC8_31:
crcComp = (uint32_t)(*crcPtr);
@@ -290,13 +296,14 @@ bool L2_CrcCheck(uint8_t* dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TY
break;
}
#else
switch (crcType){
switch (crcType)
{
case L2_CRC16_1021:
crcComp = ((uint32_t)(*(crcPtr+1))) << 8;
crcComp = ((uint32_t)(*(crcPtr + 1))) << 8;
crcComp |= (uint32_t)(*crcPtr);
break;
case L2_CRC16_8005:
crcComp = ((uint32_t)(*(crcPtr+1))) << 8;
crcComp = ((uint32_t)(*(crcPtr + 1))) << 8;
crcComp |= (uint32_t)(*crcPtr);
break;
case L2_CRC8_31:
@@ -307,21 +314,24 @@ bool L2_CrcCheck(uint8_t* dataBuff, uint32_t dataLen, uint32_t crcPos, L2_CRC_TY
break;
}
#endif
if(Status == SUCCESS){
// if ( crcVal == 0 )
// {
// return false ;
// }
// else
if(crcComp == crcVal){
if (Status == SUCCESS)
{
// if ( crcVal == 0 )
// {
// return false ;
// }
// else
if (crcComp == crcVal)
{
return true;
}
else{
else
{
return false;
}
}
else{
else
{
return false;
}
}
+66 -50
View File
@@ -7,7 +7,6 @@
#include <math.h>
#include "coord.h"
const COORD COORD_NIL = {NAN, NAN, NAN};
const COORD COORD_ZERO = {0.0, 0.0, 0.0};
const COORD COORD_ONE = {1.0, 1.0, 1.0};
@@ -15,8 +14,9 @@ const COORD COORD_X_AXIS = {1.0, 0.0, 0.0};
const COORD COORD_Y_AXIS = {0.0, 1.0, 0.0};
const COORD COORD_Z_AXIS = {0.0, 0.0, 1.0};
/** @brief Subtracts two coordinate vectors. */
COORD Coord_Sub(COORD a, COORD b) {
/** @brief Subtracts two coordinate vectors. */
COORD Coord_Sub(COORD a, COORD b)
{
COORD ret;
ret.x = a.x - b.x;
ret.y = a.y - b.y;
@@ -25,7 +25,8 @@ COORD Coord_Sub(COORD a, COORD b) {
}
/** @brief Adds two coordinate vectors. */
COORD Coord_Add(COORD a, COORD b) {
COORD Coord_Add(COORD a, COORD b)
{
COORD ret;
ret.x = a.x + b.x;
ret.y = a.y + b.y;
@@ -34,14 +35,16 @@ COORD Coord_Add(COORD a, COORD b) {
}
/** @brief Multiplies a coordinate vector by a real number. */
void Coord_ScalarMult(COORD *a, double t) {
void Coord_ScalarMult(COORD *a, double t)
{
a->x *= t;
a->y *= t;
a->z *= t;
}
/** @brief Multiplies a coordinate vector by a real number. */
COORD Coord_GetScalarMult(COORD a, double t) {
COORD Coord_GetScalarMult(COORD a, double t)
{
COORD ret;
ret.x = a.x * t;
ret.y = a.y * t;
@@ -50,14 +53,16 @@ COORD Coord_GetScalarMult(COORD a, double t) {
}
/** @brief Divides a coordinate vector by a real number. */
void Coord_ScalarDiv(COORD *a, double t) {
void Coord_ScalarDiv(COORD *a, double t)
{
a->x /= t;
a->y /= t;
a->z /= t;
}
/** @brief Divides a coordinate vector by a real number. */
COORD Coord_GetScalarDiv(COORD a, double t) {
COORD Coord_GetScalarDiv(COORD a, double t)
{
COORD ret;
ret.x = a.x / t;
ret.y = a.y / t;
@@ -66,12 +71,14 @@ COORD Coord_GetScalarDiv(COORD a, double t) {
}
/** @brief Dot product. */
inline double Coord_Dot(COORD a, COORD b) {
inline double Coord_Dot(COORD a, COORD b)
{
return (a.x * b.x + a.y * b.y + a.z * b.z);
}
/** @brief Cross product. */
COORD Coord_Cross(COORD a, COORD b) {
COORD Coord_Cross(COORD a, COORD b)
{
COORD ret;
ret.x = a.y * b.z - a.z * b.y;
ret.y = a.z * b.x - a.x * b.z;
@@ -80,7 +87,8 @@ COORD Coord_Cross(COORD a, COORD b) {
}
/** @brief Multiplies two coordinate vector in elementwise. */
COORD Coord_ElementwiseMult(COORD a, COORD b) {
COORD Coord_ElementwiseMult(COORD a, COORD b)
{
COORD ret;
ret.x = a.x * b.x;
ret.y = a.y * b.y;
@@ -89,7 +97,8 @@ COORD Coord_ElementwiseMult(COORD a, COORD b) {
}
/** @brief Divides two coordinate vector in elementwise. */
COORD Coord_ElementwiseDiv(COORD a, COORD b) {
COORD Coord_ElementwiseDiv(COORD a, COORD b)
{
COORD ret;
ret.x = a.x / b.x;
ret.y = a.y / b.y;
@@ -98,45 +107,51 @@ COORD Coord_ElementwiseDiv(COORD a, COORD b) {
}
/** @brief Calculate a coordinate vector length^2 (omits calling square root). */
double Coord_SquareLength(COORD a) {
return (a.x*a.x + a.y*a.y + a.z*a.z);
double Coord_SquareLength(COORD a)
{
return (a.x * a.x + a.y * a.y + a.z * a.z);
}
/** @brief Calculate a coordinate vector length. */
double Coord_Length(COORD a) {
double Coord_Length(COORD a)
{
return sqrt(Coord_SquareLength(a));
}
/** @brief Calculate two coordinates' distance. */
double Coord_Distance(COORD a, COORD b) {
double Coord_Distance(COORD a, COORD b)
{
return Coord_Length(Coord_Sub(a, b));
}
/** @brief Normalize coordinate vector. */
void Coord_Normalize(COORD *a) {
void Coord_Normalize(COORD *a)
{
Coord_ScalarDiv(a, Coord_Length(*a));
}
/** @brief Normalize coordinate vector. */
COORD Coord_GetNormalized(COORD a) {
COORD Coord_GetNormalized(COORD a)
{
Coord_Normalize(&a);
return a;
}
/** @brief Returns the angle between the two vectors. */
double Coord_Angle(COORD a, COORD b) {
double Coord_Angle(COORD a, COORD b)
{
Coord_Normalize(&a);
Coord_Normalize(&b);
return acos(Coord_Dot(a, b));
}
// Additional Coordinates convert
// TODO: Confirm correctness
/** @brief Convert coordinate from Launch coordinate system to ECEF. */
COORD Coord_Launch2Ecef(COORD o, COORD p, double A, double B, double lambda) {
COORD Coord_Launch2Ecef(COORD o, COORD p, double A, double B, double lambda)
{
COORD ret;
double sinA,cosA, sinB, cosB, sinL, cosL;
double sinA, cosA, sinB, cosB, sinL, cosL;
double S11, S12, S13, S21, S22, S23, S31, S32, S33;
sinA = sin(A);
cosA = cos(A);
@@ -145,51 +160,52 @@ COORD Coord_Launch2Ecef(COORD o, COORD p, double A, double B, double lambda) {
sinL = sin(lambda);
cosL = cos(lambda);
S11 = -sinA*sinL - cosA*sinB*cosL;
S12 = cosB*cosL;
S13 = -cosA*sinL + sinA*sinB*cosL;
S11 = -sinA * sinL - cosA * sinB * cosL;
S12 = cosB * cosL;
S13 = -cosA * sinL + sinA * sinB * cosL;
S21 = sinA*cosL - cosA*sinB*sinL;
S22 = cosB*sinL;
S23 = cosA*cosL + sinA*sinB*sinL;
S21 = sinA * cosL - cosA * sinB * sinL;
S22 = cosB * sinL;
S23 = cosA * cosL + sinA * sinB * sinL;
S31 = cosA*cosB;
S31 = cosA * cosB;
S32 = sinB;
S33 = -sinA*cosB;
S33 = -sinA * cosB;
ret.x = p.x*(S11 + S21 + S31) + o.x;
ret.y = p.y*(S12 + S22 + S32) + o.y;
ret.z = p.z*(S13 + S23 + S33) + o.z;
ret.x = p.x * (S11 + S21 + S31) + o.x;
ret.y = p.y * (S12 + S22 + S32) + o.y;
ret.z = p.z * (S13 + S23 + S33) + o.z;
return ret;
}
/** @brief Convert coordinate from launch coordinate system to Inertia coordinate system. */
COORD Coord_Launch2Inertia(COORD o, COORD p, double A, double B, double we, double t) {
COORD Coord_Launch2Inertia(COORD o, COORD p, double A, double B, double we, double t)
{
COORD ret;
double OmgX, OmgY, OmgZ, sinwet, coswet;
double M11, M12, M13, M21, M22, M23, M31, M32, M33;
OmgX = cos(A)*cos(B);
OmgX = cos(A) * cos(B);
OmgY = sin(B);
OmgZ = -sin(A)*cos(B);
sinwet = sin(we*t);
coswet = cos(we*t);
OmgZ = -sin(A) * cos(B);
sinwet = sin(we * t);
coswet = cos(we * t);
M11 = 1 - (1 - OmgX*OmgX)*(1-coswet);
M12 = OmgX*OmgY*(1-coswet) + OmgZ*sinwet;
M13 = OmgX*OmgZ*(1-coswet)-OmgY*sinwet;
M11 = 1 - (1 - OmgX * OmgX) * (1 - coswet);
M12 = OmgX * OmgY * (1 - coswet) + OmgZ * sinwet;
M13 = OmgX * OmgZ * (1 - coswet) - OmgY * sinwet;
M21 = OmgY*OmgX*(1-coswet) - OmgZ*sinwet;
M22 = 1-(1-OmgY*OmgY)*(1-coswet);
M23 = OmgY*OmgZ*(1-coswet) + OmgX*sinwet;
M21 = OmgY * OmgX * (1 - coswet) - OmgZ * sinwet;
M22 = 1 - (1 - OmgY * OmgY) * (1 - coswet);
M23 = OmgY * OmgZ * (1 - coswet) + OmgX * sinwet;
M31 = OmgZ*OmgX*(1-coswet) + OmgY*sinwet;
M32 = OmgZ*OmgY*(1-coswet) - OmgX*sinwet;
M33 = 1 - (1-OmgZ*OmgZ)*(1-coswet);
M31 = OmgZ * OmgX * (1 - coswet) + OmgY * sinwet;
M32 = OmgZ * OmgY * (1 - coswet) - OmgX * sinwet;
M33 = 1 - (1 - OmgZ * OmgZ) * (1 - coswet);
ret.x = p.x*(M11 + M21 + M31) + o.x;
ret.y = p.y*(M12 + M22 + M32) + o.y;
ret.z = p.z*(M13 + M23 + M33) + o.z;
ret.x = p.x * (M11 + M21 + M31) + o.x;
ret.y = p.y * (M12 + M22 + M32) + o.y;
ret.z = p.z * (M13 + M23 + M33) + o.z;
return ret;
}
@@ -4,7 +4,6 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
//
#ifndef _COORD_H
#define _COORD_H
@@ -16,7 +15,8 @@
* @ingroup utils
*/
typedef struct{
typedef struct
{
double x;
double y;
double z;
@@ -78,4 +78,3 @@ COORD Coord_GetNormalized(COORD a);
double Coord_Angle(COORD a, COORD b);
#endif
@@ -7,51 +7,55 @@
#include <math.h>
#include "eulerangles.h"
const EULERANGLES EULERANGLES_NIL = {NAN, NAN, NAN};
const EULERANGLES EULERANGLES_ZERO = {0.0, 0.0, 0.0};
/** @brief Add two EulerAngles. */
EULERANGLES EulerAngles_Add(EULERANGLES e1, EULERANGLES e2) {
EULERANGLES EulerAngles_Add(EULERANGLES e1, EULERANGLES e2)
{
EULERANGLES ret;
ret.alpha = e1.alpha + e2.alpha;
ret.beta = e1.beta + e2.beta ;
ret.beta = e1.beta + e2.beta;
ret.gamma = e1.gamma + e2.gamma;
return ret;
}
/** @brief Subtracts two EulerAngles. */
EULERANGLES EulerAngles_Sub(EULERANGLES e1, EULERANGLES e2) {
EULERANGLES EulerAngles_Sub(EULERANGLES e1, EULERANGLES e2)
{
EULERANGLES ret;
ret.alpha = e1.alpha - e2.alpha;
ret.beta = e1.beta - e2.beta ;
ret.beta = e1.beta - e2.beta;
ret.gamma = e1.gamma - e2.gamma;
return ret;
}
/** @brief Multiplies EulerAngles by a real number. */
void EulerAngles_ScalarMult(EULERANGLES *e, double f) {
void EulerAngles_ScalarMult(EULERANGLES *e, double f)
{
e->alpha *= f;
e->beta *= f;
e->beta *= f;
e->gamma *= f;
}
/** @brief Multiplies EulerAngles by a real number. */
EULERANGLES EulerAngles_GetScalarMult(EULERANGLES e, double f) {
EULERANGLES EulerAngles_GetScalarMult(EULERANGLES e, double f)
{
EulerAngles_ScalarMult(&e, f);
return e;
}
/** @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);
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);
}
/** @brief Normalize EulerAngles. */
EULERANGLES EulerAngles_GetNormalize(EULERANGLES e) {
EULERANGLES EulerAngles_GetNormalize(EULERANGLES e)
{
EulerAngles_Normalize(&e);
return e;
}
@@ -3,8 +3,8 @@
#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,18 +16,20 @@
* rotation along the Y axis rotates Z into X (leans forward), positive rotation
* along the X axis rotates Y into Z (leans right).
*/
typedef struct {
double alpha; // unit rad
double beta; // unit rad
double gamma; // unit rad
typedef struct
{
double alpha; // unit rad
double beta; // unit rad
double gamma; // unit rad
} EULERANGLES;
typedef enum {
typedef enum
{
EULERANGLES_NONE = 0,
EULERANGLES_ZYX = 1,
EULERANGLES_ZYZ = 2,
EULERANGLES_XYZ = 3,
}EULERANGLES_TYPE;
} EULERANGLES_TYPE;
extern const EULERANGLES EULERANGLES_ZERO;
extern const EULERANGLES EULERANGLES_NIL;
@@ -51,4 +53,3 @@ void EulerAngles_Normalize(EULERANGLES *e);
EULERANGLES EulerAngles_GetNormalize(EULERANGLES e);
#endif
+182 -143
View File
@@ -11,12 +11,14 @@
#include "eulerangles.h"
#include "quaternion.h"
typedef union {
typedef union
{
float value;
uint32_t raw;
} SOFT_FLOAT;
typedef union {
typedef union
{
double value;
uint64_t raw;
} SOFT_DOUBLE;
@@ -24,10 +26,11 @@ typedef union {
const SOFT_FLOAT EPS_FLOAT = {.raw = 0x34000000};
const SOFT_DOUBLE EPS_DOUBLE = {.raw = 0x3CB0000000000000};
const QUATERNION QUATERNION_IDENTITY = {1.0, 0.0, 0.0 ,0.0};
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) {
QUATERNION Quaternion_Sub(QUATERNION q1, QUATERNION q2)
{
QUATERNION ret;
ret.s = q1.s - q2.s;
ret.i = q1.i - q2.i;
@@ -37,7 +40,8 @@ QUATERNION Quaternion_Sub(QUATERNION q1, QUATERNION q2) {
}
/** @brief Adds two quaternions. */
QUATERNION Quaternion_Add(QUATERNION q1, QUATERNION q2) {
QUATERNION Quaternion_Add(QUATERNION q1, QUATERNION q2)
{
QUATERNION ret;
ret.s = q1.s + q2.s;
ret.i = q1.i + q2.i;
@@ -47,7 +51,8 @@ QUATERNION Quaternion_Add(QUATERNION q1, QUATERNION q2) {
}
/** @brief Multiplies a quaternion by a real number. */
void Quaternion_ScalarMult(QUATERNION *q, double t) {
void Quaternion_ScalarMult(QUATERNION *q, double t)
{
q->s *= t;
q->i *= t;
q->j *= t;
@@ -55,13 +60,15 @@ 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 a, double t)
{
Quaternion_ScalarMult(&a, t);
return a;
}
/** @brief Divides a quaternion by a real number. */
void Quaternion_ScalarDiv(QUATERNION *q, double t) {
void Quaternion_ScalarDiv(QUATERNION *q, double t)
{
q->s /= t;
q->i /= t;
q->j /= t;
@@ -69,15 +76,17 @@ void Quaternion_ScalarDiv(QUATERNION *q, double t) {
}
/** @brief Divides a quaternion by a real number. */
QUATERNION Quaternion_GetScalarDiv(QUATERNION q, double t) {
QUATERNION Quaternion_GetScalarDiv(QUATERNION q, double t)
{
Quaternion_ScalarDiv(&q, t);
return q;
}
/** @brief Multiplies two quaternions. */
QUATERNION Quaternion_Mult(QUATERNION q1, QUATERNION q2) {
QUATERNION Quaternion_Mult(QUATERNION q1, QUATERNION q2)
{
QUATERNION ret;
ret.s = q1.s * q2.s - (q1.i*q2.i + q1.j*q2.j + q1.k*q2.k);
ret.s = q1.s * q2.s - (q1.i * q2.i + q1.j * q2.j + q1.k * q2.k);
ret.i = q1.j * q2.k - q1.k * q2.j + q1.s * q2.i + q1.i * q2.s;
ret.j = q1.k * q2.i - q1.i * q2.k + q1.s * q2.j + q1.j * q2.s;
ret.k = q1.i * q2.j - q1.j * q2.i + q1.s * q2.k + q1.k * q2.s;
@@ -85,69 +94,80 @@ QUATERNION Quaternion_Mult(QUATERNION q1, QUATERNION q2) {
}
/** @brief Divides two quaternions. */
QUATERNION Quaternion_Div(QUATERNION q1, QUATERNION q2) {
QUATERNION Quaternion_Div(QUATERNION q1, QUATERNION q2)
{
Quaternion_Inverse(&q2);
return Quaternion_Mult(q1, q2);
}
/** @brief Dot product. */
inline double Quaternion_Dot(QUATERNION q1, QUATERNION q2) {
return (q1.s*q2.s + q1.i*q2.i + q1.j*q2.j + q1.k*q2.k);
inline double Quaternion_Dot(QUATERNION q1, QUATERNION q2)
{
return (q1.s * q2.s + q1.i * q2.i + q1.j * q2.j + q1.k * q2.k);
}
/** @brief Calculate a quaternion length^2 (omits calling square root). */
inline double Quaternion_SquareLength(QUATERNION q) {
return (q.s*q.s + q.i*q.i + q.j*q.j + q.k*q.k);
inline double Quaternion_SquareLength(QUATERNION q)
{
return (q.s * q.s + q.i * q.i + q.j * q.j + q.k * q.k);
}
/** @brief Calculate a quaternion length. */
inline double Quaternion_Length(QUATERNION q) {
inline double Quaternion_Length(QUATERNION q)
{
return sqrt(Quaternion_SquareLength(q));
}
/** @brief Normalize quaternion. */
void Quaternion_Normalize(QUATERNION *q) {
void Quaternion_Normalize(QUATERNION *q)
{
Quaternion_ScalarDiv(q, Quaternion_Length(*q));
}
/** @brief Normalize quaternion. */
QUATERNION Quaternion_GetNormalized(QUATERNION q) {
QUATERNION Quaternion_GetNormalized(QUATERNION q)
{
Quaternion_Normalize(&q);
return q;
}
/** @brief Conjugated quaternion. */
void Quaternion_Conjugated(QUATERNION *q) {
void Quaternion_Conjugated(QUATERNION *q)
{
q->i = -q->i;
q->j = -q->j;
q->k = -q->k;
}
/** @brief Conjugated quaternion. */
QUATERNION Quaternion_GetConjugated(QUATERNION q) {
QUATERNION Quaternion_GetConjugated(QUATERNION q)
{
Quaternion_Conjugated(&q);
return q;
}
/** @brief Inverse quaternion. */
void Quaternion_Inverse(QUATERNION *q) {
void Quaternion_Inverse(QUATERNION *q)
{
Quaternion_Conjugated(q);
Quaternion_ScalarDiv(q, Quaternion_SquareLength(*q));
}
/** @brief Inverse quaternion. */
QUATERNION Quaternion_GeInverse(QUATERNION q) {
QUATERNION Quaternion_GeInverse(QUATERNION q)
{
Quaternion_Inverse(&q);
return q;
}
inline double Quaternion_GetRotationAngle(QUATERNION q) {
inline double Quaternion_GetRotationAngle(QUATERNION q)
{
return (acos(q.s) * 2);
}
/** @brief Get axis of quaternion. */
COORD Quaternion_GetRotationAxis(QUATERNION q) {
COORD Quaternion_GetRotationAxis(QUATERNION q)
{
double sin_theta_inv;
COORD ret;
sin_theta_inv = 1.0 / sin(acos(q.s));
@@ -158,7 +178,8 @@ 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) {
void Quaternion_GetRotationAxisAndAngle(QUATERNION q, COORD *axis, double *angle)
{
double sin_theta_inv;
*angle = acos(q.s);
@@ -173,7 +194,8 @@ 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) {
void Quaternion_GetSwingAndTwist(QUATERNION q, COORD axis, QUATERNION *swing, QUATERNION *twist)
{
double p;
COORD v;
v.x = q.i;
@@ -191,16 +213,17 @@ void Quaternion_GetSwingAndTwist(QUATERNION q, COORD axis, QUATERNION *swing, QU
}
/** @brief rotates v by this quaternion (quaternion must be unit) */
COORD Quaternion_Rotate(QUATERNION q, COORD v) {
COORD Quaternion_Rotate(QUATERNION q, COORD v)
{
QUATERNION temp;
COORD ret;
temp.s = 0;
temp.i = v.x;
temp.j = v.y;
temp.k = v.z;
temp = Quaternion_Mult(q,temp);
temp = Quaternion_Mult(q, temp);
Quaternion_Conjugated(&q);
temp = Quaternion_Mult(temp,q);
temp = Quaternion_Mult(temp, q);
ret.x = temp.i;
ret.y = temp.j;
ret.z = temp.k;
@@ -208,122 +231,132 @@ COORD Quaternion_Rotate(QUATERNION q, COORD v) {
}
/** @brief returns the euler angles from a rotation Quaternion */
EULERANGLES Quaternion_ToEulerAngles(QUATERNION q, EULERANGLES_TYPE type) {
EULERANGLES ret;
switch (type) {
case EULERANGLES_ZYX : {
/* Covert form matlab 2023a */
// Cap all inputs to asin to 1, since values >1 produce complex
// results
// Since the quaternion is of unit length, this should never happen,
// but some code generation configuration seem to hit this edge case
// under some circumstances.
EULERANGLES Quaternion_ToEulerAngles(QUATERNION q, EULERANGLES_TYPE type)
{
EULERANGLES ret;
switch (type)
{
case EULERANGLES_ZYX:
{
/* Covert form matlab 2023a */
// Cap all inputs to asin to 1, since values >1 produce complex
// results
// Since the quaternion is of unit length, this should never happen,
// but some code generation configuration seem to hit this edge case
// under some circumstances.
double asinValue;
bool mask1, mask2;
double asinValue;
bool mask1, mask2;
asinValue = -2.0 *(q.i*q.k - q.s*q.j);
mask1 = asinValue >= 1.0 - 10*EPS_DOUBLE.value;
mask2 = asinValue <= -1.0 + 10*EPS_DOUBLE.value;
if (mask1)
asinValue = 1;
if (mask2)
asinValue = -1;
asinValue = -2.0 * (q.i * q.k - q.s * q.j);
mask1 = asinValue >= 1.0 - 10 * EPS_DOUBLE.value;
mask2 = asinValue <= -1.0 + 10 * EPS_DOUBLE.value;
if (mask1)
asinValue = 1;
if (mask2)
asinValue = -1;
if(mask1 || mask2) {
ret.alpha = (asinValue > 0) ? (-2.0 * atan2(q.i, q.s)) : (2.0 * atan2(q.i, q.s));
ret.gamma = 0;
}
else {
ret.alpha = atan2(2.0*(q.i*q.j + q.s*q.k), q.s*q.s + q.i*q.i - q.j*q.j - q.k*q.k);
ret.gamma = atan2(2.0*(q.j*q.k + q.s*q.i), q.s*q.s - q.i*q.i - q.j*q.j + q.k*q.k);
}
ret.beta = asin( asinValue );
break;
}
if (mask1 || mask2)
{
ret.alpha = (asinValue > 0) ? (-2.0 * atan2(q.i, q.s)) : (2.0 * atan2(q.i, q.s));
ret.gamma = 0;
}
else
{
ret.alpha = atan2(2.0 * (q.i * q.j + q.s * q.k), q.s * q.s + q.i * q.i - q.j * q.j - q.k * q.k);
ret.gamma = atan2(2.0 * (q.j * q.k + q.s * q.i), q.s * q.s - q.i * q.i - q.j * q.j + q.k * q.k);
}
ret.beta = asin(asinValue);
break;
}
case EULERANGLES_ZYZ : {
// TODO;
ret = EULERANGLES_NIL;
break;
}
case EULERANGLES_ZYZ:
{
// TODO;
ret = EULERANGLES_NIL;
break;
}
case EULERANGLES_XYZ : {
/* Covert form matlab 2023a */
// Prevent singularities as done in ZYX case
// Alternative to rotm2eul(quat2rotm(q), 'XYZ') with fewer
// operations
// sin(y) = R13 = 2 * (qx*qz + qy*qw)
// tan(x) = sin(x) / cos(x) = -R23 / R33
// = -2 * (qy*qz - qx*qw) / (1 - 2*(qx^2 + qy^2))
// = -2 * (qy*qz - qx*qw) / (qw^2 - qx^2 - qy^2 + qz^2)
// tan(z) = sin(z) / cos(z) = -R12 / R11
// = -2 * (qx*qy - qz*qw) / (1 - 2*(qy^2 + qz^2))
// = -2 * (qy*qz - qx*qw) / (qw^2 + qx^2 - qy^2 - qz^2)
case EULERANGLES_XYZ:
{
/* Covert form matlab 2023a */
// Prevent singularities as done in ZYX case
// Alternative to rotm2eul(quat2rotm(q), 'XYZ') with fewer
// operations
// sin(y) = R13 = 2 * (qx*qz + qy*qw)
// tan(x) = sin(x) / cos(x) = -R23 / R33
// = -2 * (qy*qz - qx*qw) / (1 - 2*(qx^2 + qy^2))
// = -2 * (qy*qz - qx*qw) / (qw^2 - qx^2 - qy^2 + qz^2)
// tan(z) = sin(z) / cos(z) = -R12 / R11
// = -2 * (qx*qy - qz*qw) / (1 - 2*(qy^2 + qz^2))
// = -2 * (qy*qz - qx*qw) / (qw^2 + qx^2 - qy^2 - qz^2)
double asinValue;
bool mask1, mask2;
double asinValue;
bool mask1, mask2;
asinValue = 2.0 *(q.i*q.k + q.s*q.j);
mask1 = asinValue >= 1.0 - 10*EPS_DOUBLE.value;
mask2 = asinValue <= -1.0 + 10*EPS_DOUBLE.value;
if (mask1)
asinValue = 1;
if (mask2)
asinValue = -1;
if(mask1 || mask2) {
ret.alpha = 0;
ret.gamma = (asinValue > 0) ? (2.0 * atan2(q.i, q.s)) : (-2.0 * atan2(q.i, q.s));
}
else {
ret.alpha = atan2(-2.0*(q.j*q.k - q.s*q.i), q.s*q.s - q.i*q.i - q.j*q.j + q.k*q.k);
ret.gamma = atan2(-2.0*(q.i*q.j - q.s*q.k), q.s*q.s + q.i*q.i - q.j*q.j - q.k*q.k);
}
ret.beta = asin( asinValue );
break;
}
asinValue = 2.0 * (q.i * q.k + q.s * q.j);
mask1 = asinValue >= 1.0 - 10 * EPS_DOUBLE.value;
mask2 = asinValue <= -1.0 + 10 * EPS_DOUBLE.value;
if (mask1)
asinValue = 1;
if (mask2)
asinValue = -1;
if (mask1 || mask2)
{
ret.alpha = 0;
ret.gamma = (asinValue > 0) ? (2.0 * atan2(q.i, q.s)) : (-2.0 * atan2(q.i, q.s));
}
else
{
ret.alpha = atan2(-2.0 * (q.j * q.k - q.s * q.i), q.s * q.s - q.i * q.i - q.j * q.j + q.k * q.k);
ret.gamma = atan2(-2.0 * (q.i * q.j - q.s * q.k), q.s * q.s + q.i * q.i - q.j * q.j - q.k * q.k);
}
ret.beta = asin(asinValue);
break;
}
default:
ret = EULERANGLES_NIL;
}
return ret;
default:
ret = EULERANGLES_NIL;
}
return ret;
}
/** @brief returns the rotation Quaternion from a euler angles */
QUATERNION Quaternion_FromeEulerAngles(EULERANGLES e, EULERANGLES_TYPE type) {
QUATERNION ret;
double cosx, sinx, cosy, siny, cosz, sinz;
cosx = cos(e.alpha * 0.5);
QUATERNION Quaternion_FromeEulerAngles(EULERANGLES e, EULERANGLES_TYPE type)
{
QUATERNION ret;
double cosx, sinx, cosy, siny, cosz, sinz;
cosx = cos(e.alpha * 0.5);
sinx = sin(e.alpha * 0.5);
cosy = cos(e.beta * 0.5);
siny = sin(e.beta * 0.5);
cosz = cos(e.gamma * 0.5);
sinz = sin(e.gamma * 0.5);
switch (type) {
case EULERANGLES_ZYX :
ret.s = cosx * cosy * cosz + sinx * siny * sinz;
ret.i = cosx * cosy * sinz - sinx * siny * cosz;
ret.j = cosx * siny * cosz + sinx * cosy * sinz;
ret.k = sinx * cosy * cosz - cosx * siny * sinz;
break;
case EULERANGLES_ZYZ :
ret.s = cosx * cosy * cosz - sinx * cosy * sinz;
ret.i = cosx * siny * sinz - sinx * siny * cosz;
ret.j = cosx * siny * cosz + sinx * siny * sinz;
ret.k = sinx * cosy * cosz + cosx * cosy * sinz;
break;
case EULERANGLES_XYZ :
ret.s = cosx * cosy * cosz - sinx * siny * sinz;
ret.i = sinx * cosy * cosz + cosx * siny * sinz;
ret.j = -sinx * cosy * sinz + cosx * siny * cosz;
ret.k = cosx * cosy * sinz + sinx * siny * cosz;
break;
default:
ret = QUATERNION_NIL;
break;
}
return ret;
switch (type)
{
case EULERANGLES_ZYX:
ret.s = cosx * cosy * cosz + sinx * siny * sinz;
ret.i = cosx * cosy * sinz - sinx * siny * cosz;
ret.j = cosx * siny * cosz + sinx * cosy * sinz;
ret.k = sinx * cosy * cosz - cosx * siny * sinz;
break;
case EULERANGLES_ZYZ:
ret.s = cosx * cosy * cosz - sinx * cosy * sinz;
ret.i = cosx * siny * sinz - sinx * siny * cosz;
ret.j = cosx * siny * cosz + sinx * siny * sinz;
ret.k = sinx * cosy * cosz + cosx * cosy * sinz;
break;
case EULERANGLES_XYZ:
ret.s = cosx * cosy * cosz - sinx * siny * sinz;
ret.i = sinx * cosy * cosz + cosx * siny * sinz;
ret.j = -sinx * cosy * sinz + cosx * siny * cosz;
ret.k = cosx * cosy * sinz + sinx * siny * cosz;
break;
default:
ret = QUATERNION_NIL;
break;
}
return ret;
}
/** @brief adapted from https://svn.code.sf.net/p/irrlicht/code/trunk/include/quaternion.h */
@@ -338,10 +371,12 @@ QUATERNION Quaternion_RotationFromTo(COORD from, COORD to)
c = Coord_Dot(from, to);
if (c >= 1.0) { // If dot == 1, vectors are the same
if (c >= 1.0)
{ // If dot == 1, vectors are the same
return QUATERNION_IDENTITY; // identity
}
else if (c <= -1.0) { // exactly opposite
else if (c <= -1.0)
{ // exactly opposite
axis = Coord_Cross(COORD_X_AXIS, from);
if (Coord_Length(axis) == 0)
@@ -367,38 +402,41 @@ QUATERNION Quaternion_RotationFromTo(COORD from, COORD to)
return ret;
}
/** @brief linear quaternion interpolation */
QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t) {
QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t)
{
QUATERNION ret;
Quaternion_ScalarMult(&q1, 1 - t);
Quaternion_ScalarMult(&q1, t);
ret = Quaternion_Add(q1, q2);
Quaternion_Normalize(&ret);
return ret;
return ret;
}
/** @brief spherical linear interpolation */
QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t) {
QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t)
{
double dot;
QUATERNION q3, ret;
dot = Quaternion_Dot(q1, q2);
/* dot = cos(theta)
if (dot < 0), q1 and q2 are more than 90 degrees apart,
so we can invert one to reduce spinning */
if (dot < 0) {
if (dot < 0)
{
dot = -dot;
q3.s = -q2.s;
q3.i = -q2.i;
q3.j = -q2.j;
q3.k = -q2.k;
}
else {
q3 = q2;
else
{
q3 = q2;
}
if (dot < 0.95) {
if (dot < 0.95)
{
double angle = acos(dot);
Quaternion_ScalarMult(&q1, sin(angle * (1 - t)));
Quaternion_ScalarMult(&q3, sin(angle * t));
@@ -407,7 +445,8 @@ QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t) {
return ret;
}
// if the angle is small, use linear interpolation
else {
else
{
return Quaternion_Lerp(q1, q3, t);
}
}
@@ -6,7 +6,8 @@
#include "eulerangles.h"
// borrowed and adapted from https://github.com/MegaManSE/willperone/blob/master/Math/quaternion.h
typedef struct {
typedef struct
{
double s;
double i;
double j;
@@ -106,4 +107,3 @@ QUATERNION Quaternion_Lerp(QUATERNION q1, QUATERNION q2, double t);
QUATERNION Quaternion_Slerp(QUATERNION q1, QUATERNION q2, double t);
#endif
File diff suppressed because it is too large Load Diff
+132 -99
View File
@@ -1,18 +1,18 @@
/*****************************************************************************/
/**
* Description: Header file for 814 linklayer functions
*
*
* Date: 2021-11-13 13:33
* LastEditors: Fan Hao
* LastEditTime: 2022-07-16 10:12
* Revisions: Rev 0.1
* History:
* 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
*
*
******************************************************************************/
#ifndef LINKLAYER814_H_
@@ -38,12 +38,13 @@
#define NET_SEEK_STAGE 4
#define NET_ERROR_STAGE -1
#define L2_PACKET_LEN_MAX 1024 //bit
#define L2_PACKET_LEN_MAX 1024 // bit
/***************** Macros (Inline Functions) Definitions *********************/
#define AssertL2Event(instPtr, event) Linklayer_EventHandler(instPtr, event)
/**************************** Type Definitions *******************************/
typedef struct {
typedef struct
{
L2_NODE_TYPE myType;
bool isInterHead;
uint8_t clustId;
@@ -51,133 +52,165 @@ typedef struct {
uint8_t headId;
uint8_t bkpHeadId;
uint8_t netScale;
PHY_INST* phyInstPtr;
TIMECTRL_INST* tmcInstPtr;
PHY_INST *phyInstPtr;
TMC_INST *tmcInstPtr;
} L2_CONFIG;
typedef struct {
typedef struct
{
uint32_t frameRx;
uint32_t frameTx;
uint32_t frameRecv;
uint32_t frameCorrect;
uint32_t bmRxCnt;
uint32_t bmTxCnt;
uint32_t bmRecvCnt;
uint32_t bmCorrectCnt;
uint32_t w2acqRxCnt;
uint32_t w2acqTxCnt;
uint32_t w2acqRecvCnt;
uint32_t w2acqCorrectCnt;
uint32_t mgmtRxCnt;
uint32_t mgmtTxCnt;
uint32_t mgmtRecvCnt;
uint32_t mgmtCorrectCnt;
uint32_t tsyncRxCnt;
uint32_t tsyncTxCnt;
uint32_t tsyncRecvCnt;
uint32_t tsyncCorrectCnt;
uint32_t svcRxCnt;
uint32_t svcTxCnt;
uint32_t svcRecvCnt;
uint32_t svcCorrectCnt;
} L2_LOG;
typedef struct
{
L2_CONFIG config;
L2_NODE_INFO myInfo;
NODE_LIST* nodeList;
L2_SCHD_POOL* schdEventPool;
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.
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* scanNetFSM; // FSM of scan net (link set up)
L2_MGMT_FSM* mgmtNetFSM; // FSM of management net (link management and time sync)
L2_SVC_FSM* serviceNetFSM; // FSM of service net (data service)
L2_RTT_FSM* rttFSM; // FSM for RTT (time sync algorithm)
uint8_t* sendPktData;
uint8_t* recvPktData;
L2_SCAN_FSM *scanFSM; // FSM of scan net (link set up)
L2_MGMT_FSM *mgmtFSM; // FSM of management net (link management and time sync)
L2_SVC_FSM *serviceFSM; // FSM of service net (data service)
L2_RTT_FSM *rttFSM; // FSM for RTT (time sync algorithm)
uint8_t *sendPktData;
uint8_t *recvPktData;
L2_LOG log;
// for MPC
uint8_t buffSwitch;
uint8_t mgmtMsgRecvCnt0;
uint8_t svcMsgRecvCnt0;
uint8_t* mgmtMsgRecvBuff0; // mgmtMsg receive data buffer
uint8_t* svcMsgRecvBuff0; // svc receive data buffer
uint8_t *mgmtMsgRecvBuff0; // mgmtMsg receive data buffer
uint8_t *svcMsgRecvBuff0; // svc receive data buffer
uint8_t mgmtMsgRecvCnt1;
uint8_t svcMsgRecvCnt1;
uint8_t* mgmtMsgRecvBuff1; // mgmtMsg receive data buffer
uint8_t* svcMsgRecvBuff1; // svc receive data buffer
uint8_t *mgmtMsgRecvBuff1; // mgmtMsg receive data buffer
uint8_t *svcMsgRecvBuff1; // svc receive data buffer
} L2_INST;
/************************** Variable Definitions *****************************/
extern L2_RTNE_TABLE_ENTRY* initTable[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY* seekTable[L2_SEEK_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY* interSeekTable[L2_NORMAL_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY* intraSeekTable[L2_NORMAL_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY* normalTable[L2_NORMAL_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *initTable[L2_INIT_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *seekTable[L2_SEEK_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *interSeekTable[L2_NORMAL_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *intraSeekTable[L2_NORMAL_RTNE_PERIOD];
extern L2_RTNE_TABLE_ENTRY *normalTable[L2_NORMAL_RTNE_PERIOD];
/************************** Function Prototypes ******************************/
// 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);
int32_t Linklayer_Start(L2_INST* instPtr);
int32_t Linklayer_Halt(L2_INST* instPtr);
int32_t Linklayer_Proc(L2_INST* instPtr);
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_SetupNextSlot(L2_INST* instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType);
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);
int32_t Linklayer_Start(L2_INST *instPtr);
int32_t Linklayer_Halt(L2_INST *instPtr);
int32_t Linklayer_Proc(L2_INST *instPtr);
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_SetupNextSlot(L2_INST *instPtr, L2_TOR_TYPE txrxMode, L2_FRAME_TYPE frameType);
// Scheduling Event
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);
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);
// Framing
void L2_FrameStateUpdate(L2_INST* instPtr);
L2_FRAME_TYPE L2_GetLastRcvFrameType(L2_INST* instPtr);
void L2_FrameStateUpdate(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetLastOptFrameType(L2_INST *instPtr);
L1_FRAME_TYPE L2_L2frame2L1frame(L2_FRAME_TYPE l2Frame);
void FrameGetChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint64_t* chunk);
void FrameInsertChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint64_t chunck);
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, uint32_t crcPos, L2_CRC_TYPE crcType);
void FrameGetChunk(BIT_ARRAY *bitarr, uint32_t offset, uint32_t numBit, uint64_t *chunk);
void FrameInsertChunk(BIT_ARRAY *bitarr, uint32_t offset, uint32_t numBit, uint64_t chunck);
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, uint32_t crcPos, L2_CRC_TYPE crcType);
// Scan Net
int32_t ScanNet_Init(L2_SCAN_FSM** scanFSMPtr);
void ScanNet_Reset(L2_SCAN_FSM* scanFSMPtr);
void ScanNet_Destroy(L2_SCAN_FSM* scanFSMPtr);
int32_t ScanNet_Proc(L2_INST* instPtr);
int32_t ScanNet_PktHandler(L2_INST* instPtr);
int32_t ScanNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry);
int32_t L2_Scan_Init(L2_SCAN_FSM **scanFSMPtr);
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);
int32_t L2_Scan_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry);
// Management Net
int32_t MgmtNet_Init(L2_MGMT_FSM** mgmtFSM);
void MgmtNet_Reset(L2_MGMT_FSM* mgmtFSM);
void MgmtNet_Destroy(L2_MGMT_FSM* mgmtFSM);
int32_t MgmtNet_PktHandler(L2_INST* instPtr);
int32_t MgmtNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry);
int32_t L2_Mgmt_Init(L2_MGMT_FSM **mgmtFSM);
void L2_Mgmt_Reset(L2_MGMT_FSM *mgmtFSM);
void L2_Mgmt_Destroy(L2_MGMT_FSM *mgmtFSM);
int32_t L2_Mgmt_PktHandler(L2_INST *instPtr);
int32_t L2_Mgmt_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry);
// Service net
int32_t ServiceNet_Init(L2_SVC_FSM** serviceFSM);
void ServiceNet_Reset(L2_SVC_FSM* serviceFSM);
void ServiceNet_Destroy(L2_SVC_FSM* serviceFSM);
int32_t ServiceNet_PktHandler(L2_INST* instPtr);
int32_t ServiceNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* schedEntry);
int32_t L2_Service_Init(L2_SVC_FSM **serviceFSM);
void L2_Service_Reset(L2_SVC_FSM *serviceFSM);
void L2_Service_Destroy(L2_SVC_FSM *serviceFSM);
int32_t L2_Service_PktHandler(L2_INST *instPtr);
int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *schedEntry);
// Miscellaneous
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);
L2_RTT_FSM* L2_GetRttFsm(L2_INST* instPtr);
bool L2_isDataAvail(L2_INST* instPtr);
bool L2_isCxn2Net(L2_INST* instPtr);
void L2_RcdShift(L2_RCD* rcd, int32_t netxVal);
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);
L2_RTT_FSM *L2_GetRttFsm(L2_INST *instPtr);
bool L2_isDataAvail(L2_INST *instPtr);
bool L2_isCxn2Net(L2_INST *instPtr);
uint32_t L2_GetFrameLen(L2_FRAME_TYPE l2FrameType);
uint32_t L2_GetLastFrameNum(L2_INST* instPtr);
uint32_t L2_GetLastSlotNum(L2_INST* instPtr);
L2_FRAME_TYPE L2_GetLastFrameType(L2_INST* instPtr);
L2_TOR_TYPE L2_GetLastTor(L2_INST* instPtr);
uint32_t L2_GetCurrentFrameNum(L2_INST* instPtr);
uint32_t L2_GetCurrentSlotNum(L2_INST* instPtr);
L2_FRAME_TYPE L2_GetCurrentFrameType(L2_INST* instPtr);
L2_TOR_TYPE L2_GetCurrentTor(L2_INST* instPtr);
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);
uint32_t L2_GetLastFrameNum(L2_INST *instPtr);
uint32_t L2_GetLastSlotNum(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetLastFrameType(L2_INST *instPtr);
L2_TOR_TYPE L2_GetLastTor(L2_INST *instPtr);
uint32_t L2_GetCurrentFrameNum(L2_INST *instPtr);
uint32_t L2_GetCurrentSlotNum(L2_INST *instPtr);
L2_FRAME_TYPE L2_GetCurrentFrameType(L2_INST *instPtr);
L2_TOR_TYPE L2_GetCurrentTor(L2_INST *instPtr);
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);
int32_t L2_TimeAlign(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool relative);
// RTT
int32_t RTT_Init(L2_RTT_FSM** rttFsmPtr);
void RTT_Reset(L2_RTT_FSM* rttFsmPtr);
void RTT_Destroy(L2_RTT_FSM* rttFsmPtr);
int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType);
int32_t RTT_Init(L2_RTT_FSM **rttFsmPtr);
void RTT_Reset(L2_RTT_FSM *rttFsmPtr);
void RTT_Destroy(L2_RTT_FSM *rttFsmPtr);
int32_t RTT_FsmUpdate(L2_INST *instPtr, L2_TOR_TYPE torType);
#endif /* LINKLAYER814_H_ */
+146 -121
View File
@@ -1,34 +1,35 @@
/*****************************************************************************/
/**
* Description: A brief description of this file
*
*
* Date: 2022-08-28 22:53
* LastEditors: Fan Hao
* LastEditTime: 2022-08-29 00:45
* Revisions: Rev x.x
* History:
* History:
* [YYYY-MM-DD]: Description of modification.
*
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
*
******************************************************************************/
#ifndef LINKLAYER814_DEF_H_
#define LINKLAYER814_DEF_H_
/***************************** Include Files *********************************/
#include <stdbool.h>
#include <inttypes.h>
#include <stdint.h>
#include "geometry/coord.h"
#include "geometry/quaternion.h"
#include "../phy_ctrl/phy_ctrl.h"
/************************** Constant Definitions *****************************/
// Common node ID definition
#define BROADCAST_ID 0x1F
#define NONE_ID 0
#define L2_BROADCAST_ID 0x1F
#define L2_NONE_ID 0
// for MPC Configure
#define MSG_STROAGE_BUFF_MAX 16384 // 16K Bytes
#define L2_MSG_STROAGE_BUFF_MAX 16384 // 16K Bytes
// Routine configure
#define L2_INIT_RTNE_PERIOD 24
@@ -42,18 +43,20 @@
#define L2_FRAMENO_NONE 0
// Common number of slots definition
#define L2_SLOTS_PER_FRAME 200
#define L2_SLOTS_PER_SUBFRAME 20
#define L2_SLOTS_PER_FRAME 200
#define L2_SLOTS_PER_SUBFRAME 20
#define NUM_SLOTS_NONE UINT32_MAX
#define NUM_SLOTS_20MS 4
#define NUM_SLOTS_10MS 2
#define NUM_SLOTS_5MS 1
#define NUM_SLOTS_SKIP 0
#define L2_NUM_SLOTS_NONE UINT32_MAX
#define L2_NUM_SLOTS_100MS 20
#define L2_NUM_SLOTS_20MS 4
#define L2_NUM_SLOTS_10MS 2
#define L2_NUM_SLOTS_5MS 1
#define L2_NUM_SLOTS_SKIP 0
/**************************** Type Definitions *******************************/
typedef struct {
typedef struct
{
uint32_t last;
uint32_t curr;
uint32_t next;
@@ -61,7 +64,8 @@ typedef struct {
/** @name Tx/Rx mode code
*/
typedef enum {
typedef enum
{
L2_TOR_SUSPEND = 0,
L2_TOR_TX = 1,
L2_TOR_RX = 2
@@ -69,25 +73,31 @@ typedef enum {
/** @name Prior information type definition
*/
typedef enum {
NONE_TYPE = 0,
HEAD_NODE = 1,
MEMBER_NODE = 2,
BACKUP_HEAD = 3
typedef enum
{
L2_NODE_NONE = 0,
L2_NODE_HEAD = 1,
L2_NODE_MEMBER = 2,
L2_NODE_BACKUP = 3
} L2_NODE_TYPE;
/** @name Node state type definition
*/
typedef enum {
NONE_STATE = 0,
INIT_STATE = 1,
NORMAL_STATE = 2,
INTRA_SEEK_STATE = 3,
INTER_SEEK_STATE = 4,
SEEK_STATE = 5
typedef enum
{
L2_NONE_STATE = 0,
L2_INIT_STATE = 1,
L2_NORMAL_STATE = 2,
L2_INTRA_SEEK_STATE = 3,
L2_INTER_SEEK_STATE = 4,
L2_SEEK_STATE = 5
} L2_NODE_STATE;
typedef struct {
/** @name Node information type definition
* The following types define the detail node info which needed by the link layer.
*/
typedef struct
{
uint8_t nodeId;
uint8_t clustId;
uint8_t headId;
@@ -95,70 +105,64 @@ typedef struct {
uint8_t beamNo;
COORD pos;
COORD speed;
QUATERNION attitude;
} L2_NODE_INFO;
/** @name L2 event enum
* A enum of L2 event types.
*/
typedef enum {
typedef enum
{
L2_EV_NONE = 0,
L2_EV_SCAN_PROC_DONE = 1,
L2_EV_MGMT_PROC_DONE = 2,
L2_EV_NET_SETUP_DONE = 3,
L2_EV_TIME_SYNC = 4,
L2_EV_RTT_RECV_UPDATE = 5,
L2_EV_LINK_SET_REQ = 6,
L2_EV_LOST_CXN = 7,
L2_EV_LOST_NODE = 8,
L2_EV_SET_FRAME_NUM = 9,
L2_EV_SET_SLOT_NUM = 10,
L2_EV_MAIN_STATE_UPDATE = 11,
L2_ROUTINE_FINISH = 12,
L2_ROUTINE_UPDATE = 13
L2_EV_NET_SETUP_DONE = 2,
L2_EV_TIME_SYNC = 3,
L2_EV_RTT_RECV_UPDATE = 4,
L2_EV_LINK_SET_REQ = 5,
L2_EV_LOST_CXN = 6,
L2_EV_LOST_NODE = 7,
L2_EV_SET_FRAME_NUM = 8,
L2_EV_SET_SLOT_NUM = 9,
L2_EV_MAIN_STATE_UPDATE = 10,
L2_ROUTINE_FINISH = 11,
L2_ROUTINE_UPDATE = 12
} L2_EVENT_TYPE;
/** @name L2 event
* A definition of L2 event instance.
*/
typedef struct {
typedef struct
{
L2_EVENT_TYPE event;
void* msg;
void *msg;
} L2_EVENT;
/** @name Slot types
* A definition of different slots.
*/
typedef enum {
SLOT_NONE = 0,
SLOT_IDLE = 1,
SLOT_INTER_SCAN_ACQ = 2,
SLOT_INTRA_SCAN_ACQ = 3,
SLOT_INTER_SCAN_BM = 4,
SLOT_INTRA_SCAN_BM = 5,
SLOT_INTER_SCAN_2W = 6,
SLOT_INTRA_SCAN_2W = 7,
SLOT_INTER_SVC = 8,
SLOT_INTRA_SVC = 9,
SLOT_INTER_MGMT = 10,
SLOT_INTRA_MGMT = 11,
SLOT_INTER_TSYNC = 12,
SLOT_INTRA_TSYNC = 13,
typedef enum
{
L2_SLOT_NONE = 0,
L2_SLOT_IDLE = 1,
L2_SLOT_INTER_SCAN_ACQ = 2,
L2_SLOT_INTRA_SCAN_ACQ = 3,
L2_SLOT_INTER_SCAN_BM = 4,
L2_SLOT_INTRA_SCAN_BM = 5,
L2_SLOT_INTER_SCAN_2W = 6,
L2_SLOT_INTRA_SCAN_2W = 7,
L2_SLOT_INTER_SVC = 8,
L2_SLOT_INTRA_SVC = 9,
L2_SLOT_INTER_MGMT = 10,
L2_SLOT_INTRA_MGMT = 11,
L2_SLOT_INTER_TSYNC = 12,
L2_SLOT_INTRA_TSYNC = 13,
} L2_SLOT_TYPE;
/** @name Frame types
* A definition of different frame types.
*/
typedef enum {
L2_CRC_NONE = 0,
L2_CRC16_1021 = 1,
L2_CRC16_8005 = 2,
L2_CRC8_31 = 3
} L2_CRC_TYPE;
/** @name Frame types
* A definition of different frame types.
*/
typedef enum {
typedef enum
{
L2_NONE_FRAME = 0,
L2_INTER_SCAN_FRAME = 1,
L2_INTRA_SCAN_FRAME = 2,
@@ -174,10 +178,22 @@ typedef enum {
L2_INTRA_SVC_FRAME = 12
} L2_FRAME_TYPE;
/** @name Frame types
* A definition of different frame types.
*/
typedef enum
{
L2_CRC_NONE = 0,
L2_CRC16_1021 = 1,
L2_CRC16_8005 = 2,
L2_CRC8_31 = 3
} L2_CRC_TYPE;
/** @name Schedule subtable entry
* A definition of Schedule subtable entry.
*/
typedef struct {
typedef struct
{
L2_SLOT_TYPE slotType : 8;
uint8_t slotSeq;
uint8_t src0;
@@ -186,8 +202,9 @@ typedef struct {
uint8_t dst1;
} L2_RTNE_TABLE_ENTRY;
// Scan net
typedef struct {
// Scan net
typedef struct
{
uint8_t NodeId;
uint8_t ClusterId;
uint32_t frameNum;
@@ -200,73 +217,79 @@ typedef struct {
uint32_t Latitude;
} L2_BM_LOG;
typedef struct {
uint8_t NodeId;
uint8_t ClusterId;
typedef struct
{
uint8_t NodeId;
uint8_t ClusterId;
uint16_t EastSpeed;
uint16_t NorthSpeed;
uint16_t UpperSpeed;
uint32_t Height;
uint32_t Longitude;
uint32_t Latitude;
L2_NODE_STATE NetStage;
L2_NODE_STATE NetStage;
uint32_t NetScanTime;
} L2_W2ACQ_LOG;
typedef enum {
NONE_STAGE = 0,
INIT_SCAN_STAGE = 1,
BM_ADVT_STAGE = 2, // Benchmark advertisement
WAY2_ACQ_STAGE = 3
typedef enum
{
L2_SCAN_NONE_STAGE = 0,
L2_SCAN_INIT_STAGE = 1,
L2_SCAN_BMADVT_STAGE = 2, // Benchmark advertisement
L2_SCANT_2WAYACQ_STAGE = 3
} SCAN_STAGE;
typedef enum {
NONE_MODE = 0,
INTRA_CLUSTER_MODE = 1,
INTER_CLUSTER_MODE = 2
} SCAN_MODE;
typedef enum
{
L2_SCAN_NONE_MODE = 0,
L2_SCAN_INTRA_MODE = 1,
L2_SCAN_INTER_MODE = 2
} L2_SCAN_MODE;
typedef struct {
bool isLocked; // init acq done.
bool isBmRcved;// bm received.
bool isAcked; // 2way acq done.
typedef struct
{
bool isLocked; // init acq done.
bool isBmRecvd; // bm received.
bool isAcked; // 2way acq done.
uint32_t scanCnt;
uint32_t bmTimeout;
uint32_t w2acqTimeout;
SCAN_STAGE scanStage; // only for member node
SCAN_MODE scanMode; // inter sanc or intra scan
SCAN_STAGE scanStage; // only for member node
L2_SCAN_MODE scanMode; // inter sanc or intra scan
L2_BM_LOG BMrcvLog;
L2_W2ACQ_LOG W2ACQrcvLog;
} L2_SCAN_FSM;
// Service Net
typedef struct {
typedef struct
{
bool isBisar;
bool isBisarEven; // Send frame at even slot at bisar mode.
uint8_t bisarDst;
uint32_t bisarEndframe;
} L2_SVC_FSM;
// Management net
typedef struct {
uint8_t wordTag ;
uint8_t msgTag ;
typedef struct
{
uint8_t wordTag;
uint8_t msgTag;
uint8_t msgSubTag;
uint8_t srcNodeId ;
uint8_t quitNodeId ;
uint8_t quitCtrlWord ;
uint8_t srcNodeId;
uint8_t quitNodeId;
uint8_t quitCtrlWord;
uint8_t nextNetState;
uint16_t EastSpeed ;
uint16_t EastSpeed;
uint16_t NorthSpeed;
uint16_t UpperSpeed;
uint32_t Height ;
uint32_t Longitude ;
uint32_t Latitude ;
uint32_t Height;
uint32_t Longitude;
uint32_t Latitude;
bool isValid;
} MGMT_MSG_RECORD;
} L2_MGMT_MSG_RECORD;
typedef struct {
typedef struct
{
uint16_t wordTag;
uint16_t msgTag;
uint16_t msgSubTag;
@@ -275,25 +298,27 @@ typedef struct {
uint16_t dstAddr;
uint32_t timeWordL;
uint32_t timeWordH;
int32_t doppler;
} RTT_MSG_RECORD;
int32_t doppler;
} L2_RTT_MSG_RECORD;
typedef struct {
typedef struct
{
bool isBisarProc;
bool isPendTimeAlloc;
bool isPendSlotAlloc;
MGMT_MSG_RECORD mgmtMsgLog;
RTT_MSG_RECORD rttMsgRspLog;
RTT_MSG_RECORD rttMsgReqLog;
L2_MGMT_MSG_RECORD mgmtMsgLog;
L2_RTT_MSG_RECORD rttMsgRspLog;
L2_RTT_MSG_RECORD rttMsgReqLog;
} L2_MGMT_FSM;
typedef struct{
L2_RTNE_TABLE_ENTRY** rtneTable;
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_CONFIG;
L2_RTNE_TABLE_ENTRY *last;
L2_RTNE_TABLE_ENTRY *curr;
L2_RTNE_TABLE_ENTRY *next;
} L2_RTNE_CONFIG;
/************************** Variable Definitions *****************************/
#endif /* LINKLAYER814_H_ */
File diff suppressed because it is too large Load Diff
+32 -33
View File
@@ -16,7 +16,7 @@
#ifndef MSG_DEF_H_
#define MSG_DEF_H_
#define L2_MSG_LEN 72 // bit
#define L2_MSG_LEN 72 // bit
#define L2_MSG_MAX 512 // bit
#define PDU_CRC_LEN 16
// ** 77 Basic Header 1 Format ** //
@@ -141,19 +141,19 @@
// ** 83 Net Scan Message - Continue 1 ** //
#define NS_MSG_CONT_1_RESV_LEN 2
#define NS_MSG_CONT_1_RESV_OFFSET 0
#define NS_MSG_CONT_1_RESV_OFFSET 0
#define NS_MSG_CONT_1_WTAG_LEN 2
#define NS_MSG_CONT_1_WTAG_OFFSET 2
#define NS_MSG_CONT_1_CONTID_LEN 4
#define NS_MSG_CONT_1_CONTID_OFFSET 4
#define NS_MSG_CONT_1_TIME_TAG_LEN 48
#define NS_MSG_CONT_1_TIME_TAG_OFFSET 8
#define NS_MSG_CONT_1_TIME_TAG_OFFSET 8
#define NS_MSG_CONT_1_EAST_SPEED_LEN 16
#define NS_MSG_CONT_1_EAST_SPEED_OFFSET 56
// ** 84 Net Scan Message - Continue 2 ** //
#define NS_MSG_CONT_2_RESV_1_LEN 2
#define NS_MSG_CONT_2_RESV_1_OFFSET 0
#define NS_MSG_CONT_2_RESV_1_OFFSET 0
#define NS_MSG_CONT_2_WTAG_LEN 2
#define NS_MSG_CONT_2_WTAG_OFFSET 2
#define NS_MSG_CONT_2_CONTID_LEN 4
@@ -169,7 +169,7 @@
// ** 85 Net Scan Message - Continue 3 ** //
#define NS_MSG_CONT_3_RESV_LEN 2
#define NS_MSG_CONT_3_RESV_OFFSET 0
#define NS_MSG_CONT_3_RESV_OFFSET 0
#define NS_MSG_CONT_3_WTAG_LEN 2
#define NS_MSG_CONT_3_WTAG_OFFSET 2
#define NS_MSG_CONT_3_CONTID_LEN 4
@@ -181,7 +181,7 @@
// ** 86 Net Scan Message - Continue 4 ** //
#define NS_MSG_CONT_4_RESV_LEN 2
#define NS_MSG_CONT_4_RESV_OFFSET 0
#define NS_MSG_CONT_4_RESV_OFFSET 0
#define NS_MSG_CONT_4_WTAG_LEN 2
#define NS_MSG_CONT_4_WTAG_OFFSET 2
#define NS_MSG_CONT_4_CONTID_LEN 4
@@ -193,7 +193,7 @@
// ** 87 Net Scan Message - Continue 5 ** //
#define NS_MSG_CONT_5_RESV_1_LEN 2
#define NS_MSG_CONT_5_RESV_1_OFFSET 0
#define NS_MSG_CONT_5_RESV_1_OFFSET 0
#define NS_MSG_CONT_5_WTAG_LEN 2
#define NS_MSG_CONT_5_WTAG_OFFSET 2
#define NS_MSG_CONT_5_CONTID_LEN 4
@@ -220,13 +220,13 @@
#define TK_MSG_INI_TQLT_LEN 4
#define TK_MSG_INI_TQLT_OFFSET 19
#define TK_MSG_INI_TBASE_ID_INDICATE_LEN 1
#define TK_MSG_INI_TBASE_ID_INDICATE_OFFSET 23
#define TK_MSG_INI_TBASE_ID_INDICATE_OFFSET 23
#define TK_MSG_INI_CSCALE_NUM_LEN 4
#define TK_MSG_INI_CSCALE_NUM_OFFSET 24
#define TK_MSG_INI_MEMBER_NUM_LEN 4
#define TK_MSG_INI_MEMBER_NUM_OFFSET 28
#define TK_MSG_INI_MUTE_TAG_LEN 1
#define TK_MSG_INI_MUTE_TAG_OFFSET 32
#define TK_MSG_INI_MUTE_TAG_OFFSET 32
#define TK_MSG_INI_NET_STATE_LEN 4
#define TK_MSG_INI_NET_STATE_OFFSET 33
#define TK_MSG_INI_RESV_LEN 35
@@ -290,7 +290,6 @@
#define TK_MSG_CONT_3_UPPER_ACC_LEN 16
#define TK_MSG_CONT_3_UPPER_ACC_OFFSET 56
// ** 94 Time Announcements Initial ** //
#define TA_MSG_SER_TAG_LEN 2
#define TA_MSG_SER_TAG_OFFSET 0
@@ -339,7 +338,6 @@
#define TA_MSG_CONT_1_RESV1_LEN 10
#define TA_MSG_CONT_1_RESV1_OFFSET 62
// ** 97 Time Announcements Continue 2 ** //
#define TA_MSG_CONT_2_RESV0_LEN 2
#define TA_MSG_CONT_2_RESV0_OFFSET 0
@@ -351,8 +349,8 @@
#define TA_MSG_CONT_2_EAST_OFFSET 8
#define TA_MSG_CONT_2_NORTH_LEN 16
#define TA_MSG_CONT_2_NORTH_OFFSET 24
#define TA_MSG_CONT_2_UPPER_LEN 16
#define TA_MSG_CONT_2_UPPER_OFFSET 40
#define TA_MSG_CONT_2_UPPER_LEN 16
#define TA_MSG_CONT_2_UPPER_OFFSET 40
#define TA_MSG_CONT_2_RESV1_LEN 16
#define TA_MSG_CONT_2_RESV1_OFFSET 56
@@ -443,7 +441,6 @@
#define RTT_REQ_CONT_RESV1_LEN 40
#define RTT_REQ_CONT_RESV1_OFFSET 32
// ** 101 RTT Response Initial Word ** //
#define RTT_RSP_SER_TAG_LEN 2
#define RTT_RSP_SER_TAG_OFFSET 0
@@ -546,7 +543,8 @@
#define BCU_MSG_RESV_LEN 19
#define BCU_MSG_RESV_OFFSET 53
typedef enum{
typedef enum
{
L2_MSG_NONE = 0,
L2_MSG_BM = 1,
L2_MSG_SCAN_INIT = 2,
@@ -577,32 +575,33 @@ typedef enum{
L2_MSG_BCU_INIT = 27,
L2_MSG_LINK_INIT = 28,
L2_MSG_LINK_CONT_1 = 29
}L2_MSG_TYPE;
} L2_MSG_TYPE;
typedef enum{
typedef enum
{
L2_PDU_HEADER_NONE = 0,
L2_PDU_HEADER_0 = 1,
L2_PDU_HEADER_1 = 2
}L2_PDU_HEADER_TYPE;
} L2_PDU_HEADER_TYPE;
// Intra-cluster frames
#define INTRA_BM_FRAME_LENGTH_MAX (232/8) // byte
#define INTRA_W2ACQ_FRAME_LENGTH_MAX (2040/8) // byte
#define INTRA_MGMT_FRAME_LENGTH_MAX (2040/8) // byte
#define INTRA_TA_FRAME_LENGTH_MAX (2040/8) // byte
#define INTRA_SVC_FRAME_LENGTH_MAX (2040/8) // byte
#define INTRA_RTT_FRAME_LENGTH_MAX (2040/8) // byte
#define INTRA_BM_FRAME_LENGTH_MAX (232 / 8) // byte
#define INTRA_W2ACQ_FRAME_LENGTH_MAX (2040 / 8) // byte
#define INTRA_MGMT_FRAME_LENGTH_MAX (2040 / 8) // byte
#define INTRA_TA_FRAME_LENGTH_MAX (2040 / 8) // byte
#define INTRA_SVC_FRAME_LENGTH_MAX (2040 / 8) // byte
#define INTRA_RTT_FRAME_LENGTH_MAX (2040 / 8) // byte
// Inter-cluster frames
#define INTER_BM_FRAME_LENGTH_MAX (312/8) // byte
#define INTER_W2ACQ_FRAME_LENGTH_MAX (712/8) // byte
#define W2ACQ_FRAME_CRC_DLEN ((NS_MSG_LEN*4)/8) //byte
#define W2ACQ_FRAME_CRC_POS ((NS_MSG_LEN*4 + NS_MSG_CONT_4_CRC_OFFSET)/8)// byte
#define INTER_BM_FRAME_LENGTH_MAX (312 / 8) // byte
#define INTER_W2ACQ_FRAME_LENGTH_MAX (712 / 8) // byte
#define W2ACQ_FRAME_CRC_DLEN ((NS_MSG_LEN * 4) / 8) // byte
#define W2ACQ_FRAME_CRC_POS ((NS_MSG_LEN * 4 + NS_MSG_CONT_4_CRC_OFFSET) / 8) // byte
#define INTER_MGMT_FRAME_LENGTH_MAX (2152/8) // byte
#define INTER_TA_FRAME_LENGTH_MAX (2152/8) // byte
#define INTER_SVC_FRAME_LENGTH_MAX (2152/8) // byte
#define INTER_RTT_FRAME_LENGTH_MAX (2152/8) // byte
#define INTER_MGMT_FRAME_LENGTH_MAX (2152 / 8) // byte
#define INTER_TA_FRAME_LENGTH_MAX (2152 / 8) // byte
#define INTER_SVC_FRAME_LENGTH_MAX (2152 / 8) // byte
#define INTER_RTT_FRAME_LENGTH_MAX (2152 / 8) // byte
extern L2_MSG_TYPE intraBmFrameMsgs[1];
extern L2_MSG_TYPE intraW2AcqFrameMsgs[6];
@@ -611,4 +610,4 @@ extern L2_MSG_TYPE taFrameMsgs[4];
extern L2_MSG_TYPE interSvcFrameMsgs[2];
extern L2_MSG_TYPE rttReqFrameMsgs[3];
extern L2_MSG_TYPE rttRspFrameMsgs[3];
#endif //MSG_DEF_H_
#endif // MSG_DEF_H_
+294 -235
View File
@@ -1,18 +1,18 @@
/*****************************************************************************/
/**
* Description: Implementations of 814 linklayer management net.
*
*
* Date: 2021-11-18 17:27
* LastEditors: Fan Hao
* LastEditTime: 2022-01-16 15:52
* Revisions: Rev 0.1
* History:
* History:
* [2022-07-16]: New branch for DiJian.
* [2021-11-18]: Initial version.
*
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
/***************************** Include Files *********************************/
@@ -25,19 +25,20 @@
#include "../common.h"
#include "node_list.h"
/************************** Constant Definitions *****************************/
#define SQUENCE_MGMT_SLOTS 0
#define INTER_MGMT_SLOTS 2
#define INTER_TSYNC_SLOTS 2
#define INTRA_MGMT_SLOTS 1
#define INTRA_TSYNC_SLOTS 1
#define NONE_MGMT_SLOTS -1
#define CONX_LOST_TH 10 // 10 count of mgmt msg no response to delete
#define TIME2QUIT 80 // time to send quit message
#define SQUENCE_MGMT_SLOTS 0
#define INTER_MGMT_SLOTS 2
#define INTER_TSYNC_SLOTS 2
#define INTRA_MGMT_SLOTS 1
#define INTRA_TSYNC_SLOTS 1
#define NONE_MGMT_SLOTS -1
#define CONX_LOST_TH 10 // 10 count of mgmt msg no response to delete
#define TIME2QUIT 80 // time to send quit message
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
typedef enum {
typedef enum
{
MGMTPKT_NONE = 0,
MGMTPKT_INTER_MGMT = 1,
MGMTPKT_INTRA_MGMT = 2,
@@ -49,8 +50,8 @@ typedef enum {
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE msgType);
static int32_t MgmtPkt_Packing(L2_INST* instPtr, MGMTPKT_TYPE pktType);
static int32_t MgmtMsg_Packing(L2_INST *instPtr, BIT_ARRAY *bitarr, L2_MSG_TYPE msgType);
static int32_t MgmtPkt_Packing(L2_INST *instPtr, MGMTPKT_TYPE pktType);
/*****************************************************************************/
/**
* @brief Packing management message to a bit array.
@@ -63,27 +64,32 @@ static int32_t MgmtPkt_Packing(L2_INST* instPtr, MGMTPKT_TYPE pktType);
* SUCCESS
*
******************************************************************************/
static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE msgType) {
static int32_t MgmtMsg_Packing(L2_INST *instPtr, BIT_ARRAY *bitarr, L2_MSG_TYPE msgType)
{
ASSERT(instPtr != NULL);
ASSERT(bitarr != NULL);
uint64_t dataChunk;
L2_RTT_FSM* rttFsmPtr = L2_GetRttFsm(instPtr);
if (msgType < L2_MSG_TK_INIT || msgType > L2_MSG_BCU_INIT) {
L2_RTT_FSM *rttFsmPtr = L2_GetRttFsm(instPtr);
if (msgType < L2_MSG_TK_INIT || msgType > L2_MSG_BCU_INIT)
{
return EPARAM;
}
if(msgType >= L2_MSG_TK_INIT && msgType <= L2_MSG_MADJ_EXTD) {
if (bitarr->num_of_bits < MGMT_MSG_LEN) {
if (msgType >= L2_MSG_TK_INIT && msgType <= L2_MSG_MADJ_EXTD)
{
if (bitarr->num_of_bits < MGMT_MSG_LEN)
{
return EPARAM;
}
}
if(msgType >= L2_MSG_RTT_REQ_INIT && msgType <= L2_MSG_RTT_RSP_CONT) {
if (bitarr->num_of_bits < RTT_MSG_LEN) {
if (msgType >= L2_MSG_RTT_REQ_INIT && msgType <= L2_MSG_RTT_RSP_CONT)
{
if (bitarr->num_of_bits < RTT_MSG_LEN)
{
return EPARAM;
}
}
memset(bitarr->words, 0x99, (size_t) (MGMT_MSG_LEN / 8));
switch (msgType) {
switch (msgType)
{
case L2_MSG_TK_INIT:
// Series tag
dataChunk = 0;
@@ -106,21 +112,23 @@ static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE
FrameInsertChunk(bitarr, TK_MSG_INI_OFFSET, TK_MSG_INI_LEN, dataChunk);
// Next net stage
if (L2_GetNodeType(instPtr) == HEAD_NODE) {
switch (instPtr->nextState) {
case INIT_STATE:
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
switch (instPtr->nextState)
{
case L2_INIT_STATE:
dataChunk = NET_INI_STAGE;
break;
case NORMAL_STATE:
case L2_NORMAL_STATE:
dataChunk = NET_NORMAL_STAGE;
break;
case INTRA_SEEK_STATE:
case L2_INTRA_SEEK_STATE:
dataChunk = NET_INTRA_SEEK_STAGE;
break;
case INTER_SEEK_STATE:
case L2_INTER_SEEK_STATE:
dataChunk = NET_INTER_SEEK_STAGE;
break;
case SEEK_STATE:
case L2_SEEK_STATE:
dataChunk = NET_SEEK_STAGE;
break;
default:
@@ -161,7 +169,7 @@ static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE
// Upper speed
dataChunk = 0xDDDD;
FrameInsertChunk(bitarr, TK_MSG_CONT_1_UPPER_SPEED_OFFSET,
TK_MSG_CONT_1_UPPER_SPEED_LEN, dataChunk);
TK_MSG_CONT_1_UPPER_SPEED_LEN, dataChunk);
// Height
dataChunk = 0xEEEEEE;
@@ -228,7 +236,7 @@ static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE
FrameInsertChunk(bitarr, TA_MSG_MSG_STAG_OFFSET, TA_MSG_MSG_STAG_LEN, dataChunk);
// Source node id
dataChunk = (L2_GetNodeId(instPtr) & 0x1F) | (((uint16_t) (L2_GetClusterId(instPtr) & 0x1F)) << 5);
dataChunk = (L2_GetNodeId(instPtr) & 0x1F) | (((uint16_t)(L2_GetClusterId(instPtr) & 0x1F)) << 5);
FrameInsertChunk(bitarr, TA_MSG_SRC_ADDR_OFFSET, TA_MSG_SRC_ADDR_LEN, dataChunk);
// Height
@@ -296,12 +304,12 @@ static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE
dataChunk = 2;
FrameInsertChunk(bitarr, RTT_REQ_MSG_OFFSET, RTT_REQ_MSG_LEN, dataChunk);
// source node address length.
// source node address.
dataChunk = (L2_GetNodeId(instPtr) & 0x1F) | (((uint16_t)(L2_GetClusterId(instPtr) & 0x1F)) << 5);
FrameInsertChunk(bitarr, RTT_REQ_SRC_ADDR_OFFSET, RTT_REQ_SRC_ADDR_LEN, dataChunk);
// destination node address length.
dataChunk = (0x02) | (((uint16_t) (L2_GetClusterId(instPtr) & 0x1F)) << 5);
// destination node address.
dataChunk = (0x02) | (((uint16_t)(L2_GetClusterId(instPtr) & 0x1F)) << 5);
FrameInsertChunk(bitarr, RTT_REQ_DST_ADDR_OFFSET, RTT_REQ_DST_ADDR_LEN, dataChunk);
break;
@@ -337,7 +345,7 @@ static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE
// message identification.
dataChunk = 29;
FrameInsertChunk(bitarr, RTT_RSP_MSG_TAG_OFFSET,
RTT_RSP_MSG_TAG_LEN, dataChunk);
RTT_RSP_MSG_TAG_LEN, dataChunk);
// message identification.
dataChunk = 2; // response
@@ -347,12 +355,12 @@ static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE
dataChunk = 2;
FrameInsertChunk(bitarr, RTT_RSP_MSG_OFFSET, RTT_RSP_MSG_LEN, dataChunk);
// source node address length.
// source node address.
dataChunk = (L2_GetNodeId(instPtr) & 0x1F) | (((uint16_t)(L2_GetClusterId(instPtr) & 0x1F)) << 5);
FrameInsertChunk(bitarr, RTT_RSP_SRC_ADDR_OFFSET, RTT_RSP_SRC_ADDR_LEN, dataChunk);
// destination node address length.
dataChunk = (0x01) | (((uint16_t) (L2_GetClusterId(instPtr) & 0x1F)) << 5);
// destination node address.
dataChunk = (0x01) | (((uint16_t)(L2_GetClusterId(instPtr) & 0x1F)) << 5);
FrameInsertChunk(bitarr, RTT_RSP_DST_ADDR_OFFSET, RTT_RSP_DST_ADDR_LEN, dataChunk);
break;
@@ -405,14 +413,14 @@ static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE
// // Quit object
// dataChunk = (L2_GetNodeId(instPtr) & 0x1F) | (((uint16_t)(L2_GetClusterId(instPtr) & 0x1F)) << 5);
// FrameInsertChunk(bitarr, NQT_MSG_OBJ_OFFSET, NQT_MSG_OBJ_LEN, dataChunk);
// L2_NODE_STATE newState = INIT_STATE;
// L2_EVENT stateEvent = {
// .event = L2_EV_MAIN_STATE_UPDATE,
// .msg = &newState
// L2_NODE_STATE newState = L2_INIT_STATE;
// L2_EVENT stateEvent = {
// .event = L2_EV_MAIN_STATE_UPDATE,
// .msg = &newState
// };
// AssertL2Event(instPtr, &stateEvent);
// L2_EVENT lostCxnEvent = {
// .event = L2_EV_LOST_CXN,
// L2_EVENT lostCxnEvent = {
// .event = L2_EV_LOST_CXN,
// .msg = NULL
// };
// AssertL2Event(instPtr, &lostCxnEvent);
@@ -425,14 +433,13 @@ static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE
break;
default:
DBG_ERROR("Unsupported message type: %d", msgType);
DBG_ERROR("Unsupported message type: %d\n", msgType);
return EPARAM;
break;
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Packing management message to a bit array.
@@ -444,64 +451,79 @@ static int32_t MgmtMsg_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_MSG_TYPE
* error code
*
******************************************************************************/
static int32_t MgmtPkt_Packing(L2_INST* instPtr, MGMTPKT_TYPE pktType) {
static int32_t MgmtPkt_Packing(L2_INST *instPtr, MGMTPKT_TYPE pktType)
{
ASSERT(instPtr != NULL);
uint8_t* buff = instPtr->sendPktData;
uint8_t *buff = instPtr->sendPktData;
uint32_t filedSize = 0;
BIT_ARRAY* mgmtPkt = bit_array_create(L2_MSG_MAX);
if (mgmtPkt == NULL) {
BIT_ARRAY *mgmtPkt = bit_array_create(L2_MSG_MAX);
if (mgmtPkt == NULL)
{
DBG_ERROR("Failed to allocate memory for scanMsg.\n");
return NUM_SLOTS_NONE;
return FAILURE;
}
switch (pktType) {
switch (pktType)
{
case MGMTPKT_INTRA_MGMT:
for (int i = 0; i < ARRAY_SIZE(intraMgmtFrameMsgs); i++) {
if (MgmtMsg_Packing(instPtr, mgmtPkt, intraMgmtFrameMsgs[i]) == SUCCESS) {
memcpy((uint8_t*)buff + (size_t) (i * (MGMT_MSG_LEN / 8)),
mgmtPkt->words, (size_t) (MGMT_MSG_LEN / 8));
for (int i = 0; i < ARRAY_SIZE(intraMgmtFrameMsgs); i++)
{
if (MgmtMsg_Packing(instPtr, mgmtPkt, intraMgmtFrameMsgs[i]) == SUCCESS)
{
memcpy((uint8_t *)buff + (size_t)(i * (MGMT_MSG_LEN / 8)),
mgmtPkt->words, (size_t)(MGMT_MSG_LEN / 8));
}
else {
else
{
DBG_ERROR("Failed to packing intraMgmtFrameMsgs[%d].\n", i);
goto failed;
}
filedSize += MGMT_MSG_LEN;
if (filedSize / 8 >= INTRA_MGMT_FRAME_LENGTH_MAX) {
if (filedSize / 8 >= INTRA_MGMT_FRAME_LENGTH_MAX)
{
DBG_ERROR("Message is too long to be properly packed.\n");
goto failed;
}
}
break;
case MGMTPKT_INTRA_RTTREQ:
for(int i = 0; i < ARRAY_SIZE(rttReqFrameMsgs); i++) {
if (MgmtMsg_Packing(instPtr, mgmtPkt, rttReqFrameMsgs[i]) == SUCCESS) {
for (int i = 0; i < ARRAY_SIZE(rttReqFrameMsgs); i++)
{
if (MgmtMsg_Packing(instPtr, mgmtPkt, rttReqFrameMsgs[i]) == SUCCESS)
{
memcpy(buff + (size_t)(i * (MGMT_MSG_LEN / 8)),
mgmtPkt->words,
(size_t)(MGMT_MSG_LEN / 8));
mgmtPkt->words,
(size_t)(MGMT_MSG_LEN / 8));
}
else {
else
{
DBG_ERROR("Failed to packing rttReqFrameMsgs[%d].\n", i);
goto failed;
}
filedSize += MGMT_MSG_LEN;
if (filedSize / 8 >= INTRA_MGMT_FRAME_LENGTH_MAX) {
if (filedSize / 8 >= INTRA_MGMT_FRAME_LENGTH_MAX)
{
DBG_ERROR("Message is too long to be properly packed.\n");
goto failed;
}
}
break;
case MGMTPKT_INTRA_RTTRSP:
for (int i = 0; i < ARRAY_SIZE(rttRspFrameMsgs); i++) {
if (MgmtMsg_Packing(instPtr, mgmtPkt, rttRspFrameMsgs[i]) == SUCCESS) {
memcpy(buff + (size_t) (i * (MGMT_MSG_LEN / 8)),
mgmtPkt->words,
(size_t) (MGMT_MSG_LEN / 8));
for (int i = 0; i < ARRAY_SIZE(rttRspFrameMsgs); i++)
{
if (MgmtMsg_Packing(instPtr, mgmtPkt, rttRspFrameMsgs[i]) == SUCCESS)
{
memcpy(buff + (size_t)(i * (MGMT_MSG_LEN / 8)),
mgmtPkt->words,
(size_t)(MGMT_MSG_LEN / 8));
}
else {
else
{
DBG_ERROR("Failed to packing rttRspFrameMsgs[%d].\n", i);
goto failed;
}
filedSize += MGMT_MSG_LEN;
if (filedSize / 8 >= INTRA_MGMT_FRAME_LENGTH_MAX) {
if (filedSize / 8 >= INTRA_MGMT_FRAME_LENGTH_MAX)
{
DBG_ERROR("Message is too long to be properly packed.\n");
goto failed;
}
@@ -521,19 +543,21 @@ failed:
/*****************************************************************************/
/**
* @brief initialize the management FSM instance.
*
*
* @param mgmtFSM A second rank pointer to management FSM instance.
*
*
* @return SUCCESS Initialize successfully
* EALLOC Memory allocation error.
*
*
******************************************************************************/
int32_t MgmtNet_Init(L2_MGMT_FSM** mgmtFSM) {
(*mgmtFSM) = (L2_MGMT_FSM*) malloc(sizeof(L2_MGMT_FSM));
if (*mgmtFSM == NULL) {
int32_t L2_Mgmt_Init(L2_MGMT_FSM **mgmtFSM)
{
(*mgmtFSM) = (L2_MGMT_FSM *)malloc(sizeof(L2_MGMT_FSM));
if (*mgmtFSM == NULL)
{
return EALLOC;
}
MgmtNet_Reset(*mgmtFSM);
L2_Mgmt_Reset(*mgmtFSM);
return SUCCESS;
}
@@ -546,34 +570,34 @@ int32_t MgmtNet_Init(L2_MGMT_FSM** mgmtFSM) {
* @return NONE
*
******************************************************************************/
void MgmtNet_Reset(L2_MGMT_FSM* mgmtFSM) {
void L2_Mgmt_Reset(L2_MGMT_FSM *mgmtFSM)
{
mgmtFSM->isBisarProc = false;
mgmtFSM->isPendSlotAlloc = false;
mgmtFSM->isPendTimeAlloc = false;
mgmtFSM->mgmtMsgLog.nextNetState = NONE_STATE;
mgmtFSM->mgmtMsgLog.nextNetState = L2_NONE_STATE;
mgmtFSM->mgmtMsgLog.isValid = false;
mgmtFSM->mgmtMsgLog.quitCtrlWord = 0;
mgmtFSM->mgmtMsgLog.quitNodeId = 0;
mgmtFSM->mgmtMsgLog.msgSubTag = 0 ;
mgmtFSM->mgmtMsgLog.msgSubTag = 0;
mgmtFSM->mgmtMsgLog.msgTag = 0;
mgmtFSM->mgmtMsgLog.wordTag = 0;
mgmtFSM->mgmtMsgLog.srcNodeId = 0;
// Position value
mgmtFSM->mgmtMsgLog.EastSpeed = 0 ;
mgmtFSM->mgmtMsgLog.NorthSpeed = 0 ;
mgmtFSM->mgmtMsgLog.UpperSpeed = 0 ;
mgmtFSM->mgmtMsgLog.Height = 0 ;
mgmtFSM->mgmtMsgLog.Longitude = 0 ;
mgmtFSM->mgmtMsgLog.Latitude = 0 ;
mgmtFSM->mgmtMsgLog.EastSpeed = 0;
mgmtFSM->mgmtMsgLog.NorthSpeed = 0;
mgmtFSM->mgmtMsgLog.UpperSpeed = 0;
mgmtFSM->mgmtMsgLog.Height = 0;
mgmtFSM->mgmtMsgLog.Longitude = 0;
mgmtFSM->mgmtMsgLog.Latitude = 0;
// clear buffer.
memset(&(mgmtFSM->rttMsgRspLog), 0x00, sizeof(RTT_MSG_RECORD));
memset(&(mgmtFSM->rttMsgReqLog), 0x00, sizeof(RTT_MSG_RECORD));
memset(&(mgmtFSM->rttMsgRspLog), 0x00, sizeof(L2_RTT_MSG_RECORD));
memset(&(mgmtFSM->rttMsgReqLog), 0x00, sizeof(L2_RTT_MSG_RECORD));
}
/*****************************************************************************/
/**
* @brief Destroy management net FSM, free all allocated memory.
@@ -583,7 +607,8 @@ void MgmtNet_Reset(L2_MGMT_FSM* mgmtFSM) {
* @return NONE
*
******************************************************************************/
void MgmtNet_Destroy(L2_MGMT_FSM* mgmtFSM){
void L2_Mgmt_Destroy(L2_MGMT_FSM *mgmtFSM)
{
free(mgmtFSM);
}
@@ -591,101 +616,112 @@ void MgmtNet_Destroy(L2_MGMT_FSM* mgmtFSM){
/**
* @brief Handles management net packet, apply time sync and other management
* net functions.
*
*
* @param instPtr a pointer to l2 instance.
*
*
* @return SUCCESS Packet was successfully handled.
* Other Packed was dumped(not addressed to me, unrecognized frame type)
*
*
******************************************************************************/
int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
int32_t L2_Mgmt_PktHandler(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
int32_t Status;
uint32_t filedSize = 0;
uint64_t dataChunk = 0;
MGMT_MSG_RECORD *mgmtMsgLog = &(instPtr->mgmtNetFSM->mgmtMsgLog);
RTT_MSG_RECORD *rttMsgRspLog = &(instPtr->mgmtNetFSM->rttMsgRspLog);
RTT_MSG_RECORD *rttMsgReqLog = &(instPtr->mgmtNetFSM->rttMsgReqLog);
L2_MGMT_MSG_RECORD *mgmtMsgLog = &(instPtr->mgmtFSM->mgmtMsgLog);
L2_RTT_MSG_RECORD *rttMsgRspLog = &(instPtr->mgmtFSM->rttMsgRspLog);
L2_RTT_MSG_RECORD *rttMsgReqLog = &(instPtr->mgmtFSM->rttMsgReqLog);
BIT_ARRAY* mgmtMsg = bit_array_create(L2_MSG_MAX);
if (mgmtMsg == NULL) {
free(mgmtMsg);
DBG_INFO("Management net handling packet...\n");
BIT_ARRAY *mgmtMsg = bit_array_create(L2_MSG_MAX);
if (mgmtMsg == NULL)
{
DBG_INFO("Failed to start handling process...\n");
return EALLOC;
}
switch (L2_GetLastFrameType(instPtr)) {
switch (L2_GetLastOptFrameType(instPtr))
{
case L2_INTER_MGMT_FRAME:
case L2_INTRA_MGMT_FRAME: {
for (int i = 0; i < ARRAY_SIZE(intraMgmtFrameMsgs); i++) {
case L2_INTRA_MGMT_FRAME:
{
for (int i = 0; i < ARRAY_SIZE(intraMgmtFrameMsgs); i++)
{
memcpy(mgmtMsg->words,
instPtr->recvPktData + (size_t) (i * (MGMT_MSG_LEN / 8)),
(size_t) (MGMT_MSG_LEN / 8));
switch (intraMgmtFrameMsgs[i]) {
instPtr->recvPktData + (size_t)(i * (MGMT_MSG_LEN / 8)),
(size_t)(MGMT_MSG_LEN / 8));
switch (intraMgmtFrameMsgs[i])
{
case L2_MSG_TK_INIT:
FrameGetChunk(mgmtMsg, TK_MSG_INI_NET_STATE_OFFSET, TK_MSG_INI_NET_STATE_LEN, &dataChunk);
mgmtMsgLog->nextNetState = (uint8_t) (dataChunk);
mgmtMsgLog->nextNetState = (uint8_t)(dataChunk);
FrameGetChunk(mgmtMsg, TK_MSG_INI_WTAG_OFFSET, TK_MSG_INI_WTAG_LEN, &dataChunk);
mgmtMsgLog->wordTag = (uint8_t) (dataChunk);
mgmtMsgLog->wordTag = (uint8_t)(dataChunk);
FrameGetChunk(mgmtMsg, TK_MSG_INI_TAG_OFFSET, TK_MSG_INI_TAG_LEN, &dataChunk);
mgmtMsgLog->msgTag = (uint8_t) (dataChunk);
mgmtMsgLog->msgTag = (uint8_t)(dataChunk);
FrameGetChunk(mgmtMsg, TK_MSG_INI_STAG_OFFSET, TK_MSG_INI_STAG_LEN, &dataChunk);
mgmtMsgLog->msgSubTag = (uint8_t) (dataChunk);
mgmtMsgLog->msgSubTag = (uint8_t)(dataChunk);
// Preventing the error response caused by unexpected bit error.
if ( mgmtMsgLog->wordTag == 3
&& mgmtMsgLog->msgTag == 28
&& mgmtMsgLog->msgSubTag == 1 ) {
if (mgmtMsgLog->wordTag == 3 && mgmtMsgLog->msgTag == 28 && mgmtMsgLog->msgSubTag == 1)
{
mgmtMsgLog->isValid = true;
}
else {
mgmtMsgLog->isValid = false ;
else
{
mgmtMsgLog->isValid = false;
}
break;
case L2_MSG_TK_EXTD :
case L2_MSG_TK_EXTD:
FrameGetChunk(mgmtMsg, TK_MSG_EXTEND_EAST_SPEED_OFFSET, TK_MSG_EXTEND_EAST_SPEED_LEN, &dataChunk);
mgmtMsgLog->EastSpeed = (uint16_t) (dataChunk);
mgmtMsgLog->EastSpeed = (uint16_t)(dataChunk);
break;
case L2_MSG_TK_CONT_1:
FrameGetChunk(mgmtMsg, TK_MSG_EXTEND_EAST_SPEED_OFFSET, TK_MSG_EXTEND_EAST_SPEED_LEN, &dataChunk);
mgmtMsgLog->EastSpeed = (uint16_t) (dataChunk);
mgmtMsgLog->EastSpeed = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, TK_MSG_CONT_1_NORTH_SPEED_OFFSET, TK_MSG_CONT_1_NORTH_SPEED_LEN, &dataChunk);
mgmtMsgLog->NorthSpeed = (uint16_t) (dataChunk);
mgmtMsgLog->NorthSpeed = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, TK_MSG_CONT_1_UPPER_SPEED_OFFSET, TK_MSG_CONT_1_UPPER_SPEED_LEN, &dataChunk);
mgmtMsgLog->UpperSpeed = (uint16_t) (dataChunk);
mgmtMsgLog->UpperSpeed = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, TK_MSG_CONT_1_HEIGHT_OFFSET, TK_MSG_CONT_1_HEIGHT_LEN, &dataChunk);
mgmtMsgLog->Height = (uint32_t) (dataChunk);
mgmtMsgLog->Height = (uint32_t)(dataChunk);
break;
case L2_MSG_TK_CONT_2:
FrameGetChunk(mgmtMsg, TK_MSG_CONT_2_LONGITUDE_OFFSET, TK_MSG_CONT_2_LONGITUDE_LEN, &dataChunk);
mgmtMsgLog->Longitude = (uint32_t) (dataChunk);
mgmtMsgLog->Longitude = (uint32_t)(dataChunk);
FrameGetChunk(mgmtMsg, TK_MSG_CONT_2_LATITUDE_OFFSET, TK_MSG_CONT_2_LATITUDE_LEN, &dataChunk);
mgmtMsgLog->Latitude = (uint32_t) (dataChunk);
mgmtMsgLog->Latitude = (uint32_t)(dataChunk);
break;
case L2_MSG_TK_CONT_3:
FrameGetChunk(mgmtMsg, TK_MSG_CONT_3_MEMBER_ADDR_OFFSET, TK_MSG_CONT_3_MEMBER_ADDR_LEN, &dataChunk);
mgmtMsgLog->srcNodeId = (uint8_t) (dataChunk & 0x1F);
mgmtMsgLog->srcNodeId = (uint8_t)(dataChunk & 0x1F);
break;
case L2_MSG_NQT_INIT:
FrameGetChunk(mgmtMsg, NQT_MSG_OBJ_OFFSET, NQT_MSG_OBJ_LEN, &dataChunk);
mgmtMsgLog->quitNodeId = (uint8_t) (dataChunk & 0x1F);
if (mgmtMsgLog->quitNodeId != L2_GetNodeId(instPtr)) {
mgmtMsgLog->quitNodeId = (uint8_t)(dataChunk & 0x1F);
if (mgmtMsgLog->quitNodeId != L2_GetNodeId(instPtr))
{
FrameGetChunk(mgmtMsg, NQT_MSG_CTRL_MUTE_OFFSET, NQT_MSG_CTRL_MUTE_LEN, &dataChunk);
mgmtMsgLog->quitCtrlWord = (uint8_t)(dataChunk & 0x7F);
if (mgmtMsgLog->quitCtrlWord == 0x01) {
if (mgmtMsgLog->quitCtrlWord == 0x01)
{
L2_DeleteNodeById(instPtr->nodeList, mgmtMsgLog->quitNodeId);
}
}
else {
else
{
DBG_WARNING("Ignore node quit request(ID not mine), target node id is [%d]\n", mgmtMsgLog->quitNodeId);
}
break;
@@ -695,31 +731,33 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
goto failed;
}
filedSize += MGMT_MSG_LEN;
if (filedSize / 8 >= INTRA_MGMT_FRAME_LENGTH_MAX) {
if (filedSize / 8 >= INTRA_MGMT_FRAME_LENGTH_MAX)
{
DBG_ERROR("Message decapsulate exceeds frame length.\n");
Status = EPARAM;
goto failed;
}
}
// Member Node update state with received message
if(L2_GetNodeId(instPtr) != HEAD_NODE && mgmtMsgLog->isValid == true ){
L2_NODE_STATE newState = NONE_STATE;
// FIXME :
switch (mgmtMsgLog->nextNetState) {
if (L2_GetNodeId(instPtr) != L2_NODE_HEAD && mgmtMsgLog->isValid == true)
{
L2_NODE_STATE newState = L2_NONE_STATE;
switch (mgmtMsgLog->nextNetState)
{
case NET_INI_STAGE:
newState = INIT_STATE;
newState = L2_INIT_STATE;
break;
case NET_NORMAL_STAGE:
newState = NORMAL_STATE;
newState = L2_NORMAL_STATE;
break;
case NET_INTRA_SEEK_STAGE:
newState = INTRA_SEEK_STATE;
newState = L2_INTRA_SEEK_STATE;
break;
case NET_INTER_SEEK_STAGE:
newState = INTER_SEEK_STATE;
newState = L2_INTER_SEEK_STATE;
break;
case NET_SEEK_STAGE:
newState = SEEK_STATE;
newState = L2_SEEK_STATE;
break;
default:
DBG_WARNING("Unknown Head node state [%d].\n", mgmtMsgLog->nextNetState);
@@ -728,57 +766,61 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
}
L2_EVENT stateUpEvent = {
.event = L2_EV_MAIN_STATE_UPDATE,
.msg = &newState
};
.msg = &newState};
AssertL2Event(instPtr, &stateUpEvent);
}
L2_RstNodeTTL(instPtr->nodeList, mgmtMsgLog->srcNodeId);
// TODO: Check
if(mgmtMsgLog->srcNodeId == L2_GetHeadId(instPtr)){
L2_TimeAlign(instPtr, L2_GetCurrentFrameNum(instPtr), L2_GetCurrentSlotNum(instPtr));
if (mgmtMsgLog->srcNodeId == L2_GetHeadId(instPtr))
{
L2_TimeAlign(instPtr, L2_GetLastFrameNum(instPtr), L2_GetLastSlotNum(instPtr), true);
}
break;
}
case L2_INTER_TSYNC_FRAME:
case L2_INTRA_TSYNC_FRAME: {
if(L2_GetNodeType(instPtr) == HEAD_NODE){
for (int i = 0; i < ARRAY_SIZE(rttReqFrameMsgs); i++) {
case L2_INTRA_TSYNC_FRAME:
{
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
for (int i = 0; i < ARRAY_SIZE(rttReqFrameMsgs); i++)
{
memcpy(mgmtMsg->words,
instPtr->recvPktData + (size_t) (i * (RTT_MSG_LEN / 8)),
(size_t) (RTT_MSG_LEN / 8));
switch (rttReqFrameMsgs[i]) {
instPtr->recvPktData + (size_t)(i * (RTT_MSG_LEN / 8)),
(size_t)(RTT_MSG_LEN / 8));
switch (rttReqFrameMsgs[i])
{
case L2_MSG_RTT_REQ_INIT:
FrameGetChunk(mgmtMsg, RTT_REQ_WTAG_OFFSET, RTT_REQ_WTAG_LEN, &dataChunk);
rttMsgReqLog->wordTag = (uint16_t) (dataChunk);
rttMsgReqLog->wordTag = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_REQ_MSG_TAG_OFFSET, RTT_REQ_MSG_TAG_LEN, &dataChunk);
rttMsgReqLog->msgTag = (uint16_t) (dataChunk);
rttMsgReqLog->msgTag = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_REQ_MSG_STAG_OFFSET, RTT_REQ_MSG_STAG_LEN, &dataChunk);
rttMsgReqLog->msgSubTag = (uint16_t) (dataChunk);
rttMsgReqLog->msgSubTag = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_REQ_MSG_OFFSET, RTT_REQ_MSG_LEN, &dataChunk);
rttMsgReqLog->msgLen = (uint16_t) (dataChunk);
rttMsgReqLog->msgLen = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_REQ_SRC_ADDR_OFFSET, RTT_REQ_SRC_ADDR_LEN, &dataChunk);
rttMsgReqLog->srcAddr = (uint16_t) (dataChunk);
rttMsgReqLog->srcAddr = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_REQ_DST_ADDR_OFFSET, RTT_REQ_DST_ADDR_LEN, &dataChunk);
rttMsgReqLog->dstAddr = (uint16_t) (dataChunk);
rttMsgReqLog->dstAddr = (uint16_t)(dataChunk);
break;
case L2_MSG_RTT_REQ_EXTD:
FrameGetChunk(mgmtMsg, RTT_REQ_EX_TTAGL_OFFSET, RTT_REQ_EX_TTAGL_LEN, &dataChunk);
rttMsgReqLog->timeWordL = (uint32_t) (dataChunk);
rttMsgReqLog->timeWordL = (uint32_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_REQ_EX_TTAGH_OFFSET, RTT_REQ_EX_TTAGH_LEN, &dataChunk);
rttMsgReqLog->timeWordH = (uint32_t) (dataChunk);
rttMsgReqLog->timeWordH = (uint32_t)(dataChunk);
break;
case L2_MSG_RTT_REQ_CONT:
FrameGetChunk(mgmtMsg, RTT_REQ_CONT_DOP_OFFSET, RTT_REQ_CONT_DOP_LEN, &dataChunk);
rttMsgReqLog->doppler = (int32_t) (dataChunk);
rttMsgReqLog->doppler = (int32_t)(dataChunk);
break;
default:
@@ -787,51 +829,55 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
goto failed;
}
filedSize += RTT_MSG_LEN;
if (filedSize / 8 >= INTRA_RTT_FRAME_LENGTH_MAX) {
if (filedSize / 8 >= INTRA_RTT_FRAME_LENGTH_MAX)
{
DBG_ERROR("Message decapsulate exceeds frame length.\n");
Status = EPARAM;
goto failed;
}
}
}
else {
for (int i = 0; i < ARRAY_SIZE(rttRspFrameMsgs); i++) {
else
{
for (int i = 0; i < ARRAY_SIZE(rttRspFrameMsgs); i++)
{
memcpy(mgmtMsg->words,
instPtr->recvPktData + (size_t) (i * (RTT_MSG_LEN / 8)),
(size_t) (RTT_MSG_LEN / 8));
switch (rttRspFrameMsgs[i]) {
instPtr->recvPktData + (size_t)(i * (RTT_MSG_LEN / 8)),
(size_t)(RTT_MSG_LEN / 8));
switch (rttRspFrameMsgs[i])
{
case L2_MSG_RTT_RSP_INIT:
FrameGetChunk(mgmtMsg, RTT_RSP_WTAG_OFFSET, RTT_RSP_WTAG_LEN, &dataChunk);
rttMsgRspLog->wordTag = (uint16_t) (dataChunk);
rttMsgRspLog->wordTag = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_RSP_MSG_TAG_OFFSET, RTT_RSP_MSG_TAG_LEN, &dataChunk);
rttMsgRspLog->msgTag = (uint16_t) (dataChunk);
rttMsgRspLog->msgTag = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_RSP_MSG_STAG_OFFSET, RTT_RSP_MSG_STAG_LEN, &dataChunk);
rttMsgRspLog->msgSubTag = (uint16_t) (dataChunk);
rttMsgRspLog->msgSubTag = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_RSP_MSG_OFFSET, RTT_RSP_MSG_LEN, &dataChunk);
rttMsgRspLog->msgLen = (uint16_t) (dataChunk);
rttMsgRspLog->msgLen = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_RSP_SRC_ADDR_OFFSET, RTT_RSP_SRC_ADDR_LEN, &dataChunk);
rttMsgRspLog->srcAddr = (uint16_t) (dataChunk);
rttMsgRspLog->srcAddr = (uint16_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_RSP_DST_ADDR_OFFSET, RTT_RSP_DST_ADDR_LEN, &dataChunk);
rttMsgRspLog->dstAddr = (uint16_t) (dataChunk);
rttMsgRspLog->dstAddr = (uint16_t)(dataChunk);
break;
case L2_MSG_RTT_RSP_EXTD:
FrameGetChunk(mgmtMsg, RTT_RSP_EX_TTAGL_OFFSET, RTT_RSP_EX_TTAGL_LEN, &dataChunk);
rttMsgRspLog->timeWordL = (uint32_t) (dataChunk);
rttMsgRspLog->timeWordL = (uint32_t)(dataChunk);
FrameGetChunk(mgmtMsg, RTT_RSP_EX_TTAGH_OFFSET, RTT_RSP_EX_TTAGH_LEN, &dataChunk);
rttMsgRspLog->timeWordH = (uint32_t) (dataChunk);
rttMsgRspLog->timeWordH = (uint32_t)(dataChunk);
break;
case L2_MSG_RTT_RSP_CONT:
FrameGetChunk(mgmtMsg, RTT_RSP_CONT_DOP_OFFSET,
RTT_RSP_CONT_DOP_LEN, &dataChunk);
rttMsgRspLog->doppler = (int32_t) (dataChunk);
RTT_RSP_CONT_DOP_LEN, &dataChunk);
rttMsgRspLog->doppler = (int32_t)(dataChunk);
break;
default:
@@ -840,7 +886,8 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
goto failed;
}
filedSize += RTT_MSG_LEN;
if (filedSize / 8 >= INTRA_RTT_FRAME_LENGTH_MAX) {
if (filedSize / 8 >= INTRA_RTT_FRAME_LENGTH_MAX)
{
DBG_ERROR("Message decapsulate exceeds frame length.\n");
Status = EPARAM;
goto failed;
@@ -850,8 +897,9 @@ int32_t MgmtNet_PktHandler(L2_INST* instPtr) {
L2_RstNodeTTL(instPtr->nodeList, rttMsgRspLog->srcAddr & 0x001F);
// TODO: Check
if((rttMsgRspLog->srcAddr&0x001F) == L2_GetHeadId(instPtr)){
L2_TimeAlign(instPtr, L2_GetCurrentFrameNum(instPtr), L2_GetCurrentSlotNum(instPtr));
if ((rttMsgRspLog->srcAddr & 0x001F) == L2_GetHeadId(instPtr))
{
L2_TimeAlign(instPtr, L2_GetLastFrameNum(instPtr), L2_GetLastSlotNum(instPtr), true);
}
break;
}
@@ -867,34 +915,35 @@ failed:
return Status;
}
/**
* @brief Helper function for check node TTL.
* @param entry
* @return trur/false
*/
static bool IsTTLValid(NODE_ENTRY* entry) {
static bool IsTTLValid(NODE_ENTRY *entry)
{
ASSERT(entry != NULL);
return (entry->ttlCnt <= CONX_LOST_TH);
}
/*****************************************************************************/
/**
* @brief Management net FSM routine.
*
* @param mgmtFSM
*
* @param mgmtFSM
* mainState
*
*
* @return Slot has be used.
*
*
******************************************************************************/
int32_t MgmtNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry){
int32_t L2_Mgmt_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
{
ASSERT(instPtr != NULL);
int32_t Status;
DBG_INFO("-------- MgmtNet Routine --------\n");
if(rtneEntry->slotSeq != 0){
if (rtneEntry->slotSeq != 0)
{
return SUCCESS;
}
@@ -903,66 +952,76 @@ int32_t MgmtNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry){
// Determine next slot TOR state.
L2_TOR_TYPE torState = L2_TOR_SUSPEND;
if ((rtneEntry->src0 == L2_GetNodeId(instPtr))
|| (rtneEntry->src1 == L2_GetNodeId(instPtr))) {
if ((rtneEntry->src0 == L2_GetNodeId(instPtr)) || (rtneEntry->src1 == L2_GetNodeId(instPtr)))
{
torState = L2_TOR_TX;
}
else if ((rtneEntry->dst0 == L2_GetNodeId(instPtr))
|| (rtneEntry->dst1 == L2_GetNodeId(instPtr))) {
else if ((rtneEntry->dst0 == L2_GetNodeId(instPtr)) || (rtneEntry->dst1 == L2_GetNodeId(instPtr)))
{
torState = L2_TOR_RX;
}
else {
else
{
torState = L2_TOR_SUSPEND;
}
// Update RTT FSM if needed.
if (L2_GetLastFrameType(instPtr) == L2_INTRA_TSYNC_FRAME && L2_GetLastTor(instPtr) == L2_TOR_RX) {
RTT_FsmUpdate(instPtr, L2_TOR_RX);
}
if (rtneEntry->slotType == SLOT_INTRA_TSYNC) {
if(torState == L2_TOR_TX) {
// Update RTT FSM if needed.
if (rtneEntry->slotType == L2_SLOT_INTRA_TSYNC)
{
if (torState == L2_TOR_TX)
{
RTT_FsmUpdate(instPtr, L2_TOR_TX);
}
else if (torState == L2_TOR_RX)
{
L2_SCHD_EVENT* rttRxEvent = L2_CreatNewSchdEvent(instPtr->schdEventPool, L2_EV_RTT_RECV_UPDATE, true);
if(rttRxEvent == NULL) {
L2_SCHD_EVENT *rttRxEvent = L2_CreatNewSchdEvent(instPtr->schdEventPool, L2_EV_RTT_RECV_UPDATE, true);
if (rttRxEvent == NULL)
{
DBG_ERROR("Failed to initialize rtt event.\n");
}
// Schedule rtt update after receive process end.
Status = L2_ScheduleEventAfter(instPtr, rttRxEvent, INTRA_TSYNC_SLOTS + 1);
}
}
switch (rtneEntry->slotType) {
case SLOT_INTER_MGMT:
// TODO:
switch (rtneEntry->slotType)
{
case L2_SLOT_INTER_MGMT:
// TODO:
L2_SetupNextSlot(instPtr, torState, L2_INTER_MGMT_FRAME);
break;
case SLOT_INTRA_MGMT:
memset(instPtr->sendPktData, 0xAA, INTRA_MGMT_FRAME_LENGTH_MAX);
if (torState == L2_TOR_TX) {
if(MgmtPkt_Packing(instPtr, MGMTPKT_INTRA_MGMT) != SUCCESS) {
case L2_SLOT_INTRA_MGMT:
memset(instPtr->sendPktData, 0xAA, L2_PACKET_LEN_MAX);
if (torState == L2_TOR_TX)
{
if (MgmtPkt_Packing(instPtr, MGMTPKT_INTRA_MGMT) != SUCCESS)
{
Status = FAILURE;
goto routine_err;
}
}
L2_SetupNextSlot(instPtr, torState, L2_INTRA_MGMT_FRAME);
break;
case SLOT_INTER_TSYNC:
// TODO:
case L2_SLOT_INTER_TSYNC:
// TODO:
L2_SetupNextSlot(instPtr, torState, L2_INTER_TSYNC_FRAME);
break;
case SLOT_INTRA_TSYNC:
if (torState == L2_TOR_TX) {
memset(instPtr->sendPktData, 0xAA, INTRA_RTT_FRAME_LENGTH_MAX);
if(L2_GetNodeType(instPtr) == HEAD_NODE){
if(MgmtPkt_Packing(instPtr, MGMTPKT_INTRA_RTTREQ) != SUCCESS) {
case L2_SLOT_INTRA_TSYNC:
if (torState == L2_TOR_TX)
{
memset(instPtr->sendPktData, 0xAA, L2_PACKET_LEN_MAX);
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
if (MgmtPkt_Packing(instPtr, MGMTPKT_INTRA_RTTREQ) != SUCCESS)
{
Status = FAILURE;
goto routine_err;
}
}
else {
if(MgmtPkt_Packing(instPtr, MGMTPKT_INTRA_RTTRSP) != SUCCESS) {
else
{
if (MgmtPkt_Packing(instPtr, MGMTPKT_INTRA_RTTRSP) != SUCCESS)
{
Status = FAILURE;
goto routine_err;
}
@@ -978,35 +1037,35 @@ int32_t MgmtNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry){
/*************************************************/
// Update link layer state...
if (L2_GetNodeType(instPtr) == HEAD_NODE) {
L2_NODE_STATE newState = NONE_STATE;
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
L2_NODE_STATE newState = L2_NONE_STATE;
L2_EVENT stateEvent = {
.event = L2_EV_MAIN_STATE_UPDATE,
.msg = &newState
};
if (L2_GetNodeListLen(instPtr->nodeList) < instPtr->config.netScale
&& L2_GetMainState(instPtr) != INTRA_SEEK_STATE) {
newState = INTRA_SEEK_STATE;
.msg = &newState};
if (L2_GetNodeListLen(instPtr->nodeList) < instPtr->config.netScale - 1)
{
newState = L2_INTRA_SEEK_STATE;
AssertL2Event(instPtr, &stateEvent);
}
else if(L2_GetNodeListLen(instPtr->nodeList) >= instPtr->config.netScale &&
L2_GetMainState(instPtr) != NORMAL_STATE){
newState = NORMAL_STATE;
else
{
newState = L2_NORMAL_STATE;
AssertL2Event(instPtr, &stateEvent);
}
}
else{ // MEMBER_NODE or BACKUP_HEAD
if(L2_isNodeInList(instPtr->nodeList, L2_GetHeadId(instPtr)) == false){
L2_NODE_STATE newState = INIT_STATE;
else
{ // L2_NODE_MEMBER or BACKUP_HEAD
if (L2_isNodeInList(instPtr->nodeList, L2_GetHeadId(instPtr)) == false)
{
L2_NODE_STATE newState = L2_INIT_STATE;
L2_EVENT stateEvent = {
.event = L2_EV_MAIN_STATE_UPDATE,
.msg = &newState
};
.msg = &newState};
AssertL2Event(instPtr, &stateEvent);
L2_EVENT lostCxnEvent = {
.event = L2_EV_LOST_CXN,
.msg = NULL
};
.msg = NULL};
AssertL2Event(instPtr, &lostCxnEvent);
DBG_WARNING("Lost connection with head node [%d].\n", L2_GetHeadId(instPtr));
}
File diff suppressed because it is too large Load Diff
+103 -65
View File
@@ -22,18 +22,17 @@
#include "../error.h"
#include "../common.h"
#ifdef _MPC_CTRL
#endif
/************************** Constant Definitions *****************************/
#define SQUENCE_SVC_SLOTS 0
#define INER_SVC_SLOTS 2
#define INRA_SVC_SLOTS 1
#define NONE_SVC_SLOTS 0
#define TEST_UDU_PDLEN 16
#define TEST_UDU_LEN (UDUH_LEN/8 + TEST_UDU_PDLEN + PDU_CRC_LEN/8 )
#define INER_SVC_SLOTS 2
#define INRA_SVC_SLOTS 1
#define NONE_SVC_SLOTS 0
#define TEST_UDU_PDLEN 16
#define TEST_UDU_LEN (UDUH_LEN / 8 + TEST_UDU_PDLEN + PDU_CRC_LEN / 8)
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
@@ -59,13 +58,14 @@
* SUCCESS
*
******************************************************************************/
static int UduHeader_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, uint8_t dst, uint32_t dataLen){
static int UduHeader_Packing(L2_INST *instPtr, BIT_ARRAY *bitarr, uint8_t dst, uint32_t dataLen)
{
ASSERT(bitarr != NULL);
if(bitarr->num_of_bits < UDUH_LEN){
if (bitarr->num_of_bits < UDUH_LEN)
{
return EPARAM;
}
uint64_t dataChunk = 0;
memset(bitarr->words, 0xF0, (size_t)(UDUH_LEN/8));
// priority
dataChunk = 1;
FrameInsertChunk(bitarr, UDUH_PRI_OFFSET, UDUH_PRI_LEN, dataChunk);
@@ -76,10 +76,10 @@ static int UduHeader_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, uint8_t dst, u
dataChunk = dataLen;
FrameInsertChunk(bitarr, UDUH_LENGTH_OFFSET, UDUH_LENGTH_LEN, dataChunk);
// source node id
dataChunk = (L2_GetNodeId(instPtr) & 0x1F)|((L2_GetClusterId(instPtr) & 0x1F) << 5);
dataChunk = (L2_GetNodeId(instPtr) & 0x1F) | ((L2_GetClusterId(instPtr) & 0x1F) << 5);
FrameInsertChunk(bitarr, UDUH_SRC_ADDR_OFFSET, UDUH_SRC_ADDR_LEN, dataChunk);
// destination node id
dataChunk = (dst & 0x1F)|((L2_GetClusterId(instPtr) & 0x1F) << 5);
dataChunk = (dst & 0x1F) | ((L2_GetClusterId(instPtr) & 0x1F) << 5);
FrameInsertChunk(bitarr, UDUH_DST_ADDR_OFFSET, UDUH_DST_ADDR_LEN, dataChunk);
// UDU Sequence number
dataChunk = 0;
@@ -108,17 +108,20 @@ static int UduHeader_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, uint8_t dst, u
* SUCCESS
*
******************************************************************************/
static int PduHeader_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_PDU_HEADER_TYPE headerType, uint8_t dst){
static int PduHeader_Packing(L2_INST *instPtr, BIT_ARRAY *bitarr, L2_PDU_HEADER_TYPE headerType, uint8_t dst)
{
ASSERT(bitarr != NULL);
if(headerType < L2_PDU_HEADER_0 || headerType > L2_PDU_HEADER_1){
if (headerType < L2_PDU_HEADER_0 || headerType > L2_PDU_HEADER_1)
{
return EPARAM;
}
uint64_t dataChunk = 0;
if(headerType == L2_PDU_HEADER_0){
if(bitarr->num_of_bits < PDUH0_LEN){
if (headerType == L2_PDU_HEADER_0)
{
if (bitarr->num_of_bits < PDUH0_LEN)
{
return EPARAM;
}
memset(bitarr->words, 0xF0, (size_t)(PDUH0_LEN/8));
// PDU type
dataChunk = 0;
FrameInsertChunk(bitarr, PDUH0_TYPE_OFFSET, PDUH0_TYPE_LEN, dataChunk);
@@ -126,22 +129,23 @@ static int PduHeader_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_PDU_HEADER_
dataChunk = INTRA_SVC_FRAME_LENGTH_MAX;
FrameInsertChunk(bitarr, PDUH0_LENGTH_OFFSET, PDUH0_LENGTH_LEN, dataChunk);
// source node id
dataChunk = (L2_GetNodeId(instPtr) & 0x1F)|((L2_GetClusterId(instPtr) & 0x1F) << 5);
dataChunk = (L2_GetNodeId(instPtr) & 0x1F) | ((L2_GetClusterId(instPtr) & 0x1F) << 5);
FrameInsertChunk(bitarr, PDUH0_SRC_ADDR_OFFSET, PDUH0_SRC_ADDR_LEN, dataChunk);
// destination node id
dataChunk = (dst & 0x1F)|((L2_GetClusterId(instPtr) & 0x1F) << 5);
dataChunk = (dst & 0x1F) | ((L2_GetClusterId(instPtr) & 0x1F) << 5);
FrameInsertChunk(bitarr, PDUH0_DST_ADDR_OFFSET, PDUH0_DST_ADDR_LEN, dataChunk);
// Sequence number
dataChunk = 0;
FrameInsertChunk(bitarr, PDUH0_SEQ_NUM_OFFSET, PDUH0_SEQ_NUM_LEN, dataChunk);
// Append CRC
L2_CrcAppend((uint8_t*)bitarr->words, PDUH0_HEADER_CRC_OFFSET/8, PDUH0_HEADER_CRC_OFFSET/8, L2_CRC8_31);
L2_CrcAppend((uint8_t *)bitarr->words, PDUH0_HEADER_CRC_OFFSET / 8, PDUH0_HEADER_CRC_OFFSET / 8, L2_CRC8_31);
}
else if(headerType == L2_PDU_HEADER_1){
if(bitarr->num_of_bits < PDUH1_LEN){
else if (headerType == L2_PDU_HEADER_1)
{
if (bitarr->num_of_bits < PDUH1_LEN)
{
return EPARAM;
}
memset(bitarr->words, 0xF0, (size_t)(PDUH1_LEN/8));
// PDU type
dataChunk = 1;
FrameInsertChunk(bitarr, PDUH1_TYPE_OFFSET, PDUH1_TYPE_LEN, dataChunk);
@@ -149,16 +153,17 @@ static int PduHeader_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_PDU_HEADER_
dataChunk = INTRA_SVC_FRAME_LENGTH_MAX;
FrameInsertChunk(bitarr, PDUH1_LENGTH_OFFSET, PDUH1_LENGTH_LEN, dataChunk);
// source node id
dataChunk = (L2_GetNodeId(instPtr) & 0x1F)|((L2_GetClusterId(instPtr) & 0x1F) << 5);
dataChunk = (L2_GetNodeId(instPtr) & 0x1F) | ((L2_GetClusterId(instPtr) & 0x1F) << 5);
FrameInsertChunk(bitarr, PDUH1_SRC_ADDR_OFFSET, PDUH1_SRC_ADDR_LEN, dataChunk);
// destination node id
dataChunk = (dst & 0x1F)|((L2_GetClusterId(instPtr) & 0x1F) << 5);
dataChunk = (dst & 0x1F) | ((L2_GetClusterId(instPtr) & 0x1F) << 5);
FrameInsertChunk(bitarr, PDUH1_DST_ADDR_OFFSET, PDUH1_DST_ADDR_LEN, dataChunk);
// Slice tage...
// Append CRC
L2_CrcAppend((uint8_t*)bitarr->words, PDUH1_HEADER_CRC_OFFSET/8, PDUH1_HEADER_CRC_OFFSET/8, L2_CRC8_31);
L2_CrcAppend((uint8_t *)bitarr->words, PDUH1_HEADER_CRC_OFFSET / 8, PDUH1_HEADER_CRC_OFFSET / 8, L2_CRC8_31);
}
else{
else
{
return FAILURE;
}
return SUCCESS;
@@ -174,23 +179,46 @@ static int PduHeader_Packing(L2_INST* instPtr, BIT_ARRAY* bitarr, L2_PDU_HEADER_
* Other Initialize failed.
*
******************************************************************************/
int32_t ServiceNet_Init(L2_SVC_FSM** serviceFSM) {
(*serviceFSM) = (L2_SVC_FSM*) malloc(sizeof(L2_SVC_FSM));
if (*serviceFSM == NULL) {
int32_t L2_Service_Init(L2_SVC_FSM **serviceFSM)
{
*serviceFSM = (L2_SVC_FSM *)malloc(sizeof(L2_SVC_FSM));
if (*serviceFSM == NULL)
{
return EALLOC;
}
ServiceNet_Reset(*serviceFSM);
L2_Service_Reset(*serviceFSM);
return SUCCESS;
}
void ServiceNet_Reset(L2_SVC_FSM* serviceFSM) {
/*****************************************************************************/
/**
* @brief Reset ServiceNet FSM
*
* @param scanFsmPtr a pointer to service net finite state machine
*
* @return NONE
*
******************************************************************************/
void L2_Service_Reset(L2_SVC_FSM *serviceFSM)
{
ASSERT(serviceFSM != NULL);
serviceFSM->isBisar = false;
serviceFSM->isBisarEven = false;
serviceFSM->bisarDst = NONE_ID;
serviceFSM->bisarDst = L2_NONE_ID;
}
void ServiceNet_Destroy(L2_SVC_FSM* serviceFSM){
/*****************************************************************************/
/**
* @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);
}
/*****************************************************************************/
@@ -203,8 +231,11 @@ void ServiceNet_Destroy(L2_SVC_FSM* serviceFSM){
* other error occurred.
*
******************************************************************************/
int32_t ServiceNet_PktHandler(L2_INST* instPtr) {
int32_t L2_Service_PktHandler(L2_INST *instPtr)
{
// TODO:
DBG_INFO("Scan net handling packet...\n");
return SUCCESS;
}
@@ -213,71 +244,78 @@ int32_t ServiceNet_PktHandler(L2_INST* instPtr) {
* @brief Service net FSM procedure.
*
* @param instPtr a pointer to linklayer layer instance
* @param rtneEntry
* @param rtneEntry
*
* @return Slot has been used.
*
******************************************************************************/
int32_t ServiceNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntry) {
int32_t L2_Service_Routine(L2_INST *instPtr, const L2_RTNE_TABLE_ENTRY *rtneEntry)
{
ASSERT(instPtr != NULL);
int32_t Status;
L2_TOR_TYPE torState;
DBG_INFO("-------- ServiceNet Routine --------\n");
if(rtneEntry->slotSeq != 0){
if (rtneEntry->slotSeq != 0)
{
return SQUENCE_SVC_SLOTS;
}
// Determine TOR State.
if(rtneEntry->src0 == L2_GetNodeId(instPtr)){
if (rtneEntry->src0 == L2_GetNodeId(instPtr))
{
torState = L2_TOR_TX;
}
else if(rtneEntry->dst0 == L2_GetNodeId(instPtr)){
else if (rtneEntry->dst0 == L2_GetNodeId(instPtr))
{
torState = L2_TOR_RX;
}
else{
else
{
torState = L2_TOR_SUSPEND;
}
BIT_ARRAY* svcMsg = bit_array_create(L2_MSG_MAX);
if(svcMsg == NULL){
BIT_ARRAY *svcMsg = bit_array_create(L2_MSG_MAX);
if (svcMsg == NULL)
{
DBG_ERROR("Failed to allocate memory for svcMsg.\n");
return NUM_SLOTS_NONE;
return FAILURE;
}
memset(instPtr->sendPktData, 0xCC, (size_t)(INTRA_SVC_FRAME_LENGTH_MAX));
switch(rtneEntry->slotType){
case SLOT_INTER_SVC:
switch (rtneEntry->slotType)
{
case L2_SLOT_INTER_SVC:
L2_SetupNextSlot(instPtr, torState, L2_INTER_SVC_FRAME);
break;
case SLOT_INTRA_SVC:
if(torState == L2_TOR_TX){
//TODO:
memset(instPtr->sendPktData, 0xAA, INTRA_SVC_FRAME_LENGTH_MAX);
case L2_SLOT_INTRA_SVC:
if (torState == L2_TOR_TX)
{
// TODO:
memset(instPtr->sendPktData, 0xAA, L2_PACKET_LEN_MAX);
// Pack PDU header
if(PduHeader_Packing(instPtr, svcMsg, L2_PDU_HEADER_0, rtneEntry->dst0) != SUCCESS){
if (PduHeader_Packing(instPtr, svcMsg, L2_PDU_HEADER_0, rtneEntry->dst0) != SUCCESS)
{
DBG_ERROR("Failed to packing PduHeader.\n");
Status = FAILURE;
goto routine_err;
}
memcpy(instPtr->sendPktData, svcMsg->words, (size_t)(PDUH0_LEN/8));
memcpy(instPtr->sendPktData, svcMsg->words, (size_t)(PDUH0_LEN / 8));
// Pack UDU Header
if(UduHeader_Packing(instPtr, svcMsg, rtneEntry->dst0,
INTRA_SVC_FRAME_LENGTH_MAX-(PDUH0_LEN+MSG_KEY_LENGTH_LEN)/8)
!= SUCCESS){
if (UduHeader_Packing(instPtr, svcMsg, rtneEntry->dst0,
INTRA_SVC_FRAME_LENGTH_MAX - (PDUH0_LEN + MSG_KEY_LENGTH_LEN) / 8) != SUCCESS)
{
DBG_ERROR("Failed to packing UduHeader.\n");
Status = FAILURE;
goto routine_err;
}
memcpy(instPtr->sendPktData + ((PDUH0_LEN+MSG_KEY_LENGTH_LEN)/8), svcMsg->words, (size_t)(UDUH_LEN/8));
memcpy(instPtr->sendPktData + ((PDUH0_LEN + MSG_KEY_LENGTH_LEN) / 8), svcMsg->words, (size_t)(UDUH_LEN / 8));
// For ZhiQiang
// Payload Byte3, bit0~2: message class, bit3~7 message subclass
// FIXME: message class tag 0x01, only for test.
memset(instPtr->sendPktData+((PDUH0_LEN+MSG_KEY_LENGTH_LEN+UDUH_LEN)/8) + 3, 0x01, 1);
L2_CrcAppend(instPtr->sendPktData + ((PDUH0_LEN+MSG_KEY_LENGTH_LEN)/8),
INTRA_SVC_FRAME_LENGTH_MAX-(PDUH0_LEN+MSG_KEY_LENGTH_LEN+PDU_CRC_LEN)/8,
INTRA_SVC_FRAME_LENGTH_MAX-(PDUH0_LEN+MSG_KEY_LENGTH_LEN+PDU_CRC_LEN)/8,
L2_CRC16_8005
);
memset(instPtr->sendPktData + ((PDUH0_LEN + MSG_KEY_LENGTH_LEN + UDUH_LEN) / 8) + 3, 0x01, 1);
L2_CrcAppend(instPtr->sendPktData + ((PDUH0_LEN + MSG_KEY_LENGTH_LEN) / 8),
INTRA_SVC_FRAME_LENGTH_MAX - (PDUH0_LEN + MSG_KEY_LENGTH_LEN + PDU_CRC_LEN) / 8,
INTRA_SVC_FRAME_LENGTH_MAX - (PDUH0_LEN + MSG_KEY_LENGTH_LEN + PDU_CRC_LEN) / 8,
L2_CRC16_8005);
}
L2_SetupNextSlot(instPtr, torState, L2_INTRA_SVC_FRAME);
break;
@@ -287,9 +325,9 @@ int32_t ServiceNet_Routine(L2_INST* instPtr, const L2_RTNE_TABLE_ENTRY* rtneEntr
Status = FAILURE;
goto routine_err;
}
bit_array_free(svcMsg);// free memory
bit_array_free(svcMsg); // free memory
return SUCCESS;
routine_err:
bit_array_free(svcMsg);// free memory
bit_array_free(svcMsg); // free memory
return Status;
}
+147 -90
View File
@@ -21,12 +21,13 @@
#include <stdbool.h>
#include "linklayer814_types.h"
#include "node_list.h"
#include "../util/list.h"
#include "../util/clist.h"
#include "../common.h"
#include "../error.h"
/***************** Macros (Inline Functions) Definitions *********************/
inline uint32_t L2_GetNodeListLen(NODE_LIST *list) {
inline uint32_t L2_GetNodeListLen(NODE_LIST *list)
{
ASSERT(list != NULL);
return list->len;
}
@@ -38,18 +39,33 @@ static NODE_ENTRY util_entry;
/**
* @brief helper function to free node entry.
*/
static void entry_free(void* val){
static void entry_free(void *val)
{
free(val);
}
/**
* @brief helper function to match node entries by nodeIds
*/
static bool entry_match(void* a, void* b){
static int8_t entry_compare(void *a, void *b)
{
ASSERT(a != NULL);
ASSERT(b != NULL);
return (((NODE_ENTRY*)a)->nodeInfo.nodeId
== ((NODE_ENTRY*)b)->nodeInfo.nodeId);
register uint8_t idA, idB;
idA = ((NODE_ENTRY *)a)->nodeInfo.nodeId;
idB = ((NODE_ENTRY *)b)->nodeInfo.nodeId;
if (idA == idB)
{
return 0;
}
else if (idA < idB)
{
return -1;
}
else
{
return 1;
}
}
/*****************************************************************************/
/**
@@ -61,13 +77,15 @@ static bool entry_match(void* a, void* b){
* ENOMEM - not enough memory.
*
******************************************************************************/
int32_t L2_NodeList_Init(NODE_LIST **list) {
(*list) = list_new();
if (*list == NULL) {
int32_t L2_NodeList_Init(NODE_LIST **list)
{
(*list) = clist_new();
if (*list == NULL)
{
return ENOMEM;
}
(*list)->free = entry_free;
(*list)->match = entry_match;
(*list)->compare = entry_compare;
return SUCCESS;
}
@@ -79,9 +97,10 @@ int32_t L2_NodeList_Init(NODE_LIST **list) {
*NONE
*
******************************************************************************/
void L2_NodeList_Clear(NODE_LIST *list){
void L2_NodeList_Clear(NODE_LIST *list)
{
ASSERT(list != NULL);
list_clear(list);
clist_clear(list);
}
/*****************************************************************************/
@@ -93,12 +112,13 @@ void L2_NodeList_Clear(NODE_LIST *list){
* @return NONE
*
******************************************************************************/
void L2_NodeList_Destroy(NODE_LIST *list){
list_destroy(list);
void L2_NodeList_Destroy(NODE_LIST *list)
{
clist_destroy(list);
}
/*****************************************************************************/
/**
* @brief Get node entry frome node list base on node id.
* @brief Get node entry from node list base on node id.
*
* @param list
* @param nodeId
@@ -107,20 +127,21 @@ void L2_NodeList_Destroy(NODE_LIST *list){
* NULL if node dose not exist.
*
******************************************************************************/
NODE_ENTRY* L2_GetNodeById(NODE_LIST *list, uint8_t nodeId) {
NODE_ENTRY *L2_GetNodeById(NODE_LIST *list, uint8_t nodeId)
{
ASSERT(list != NULL);
util_entry.nodeInfo.nodeId = nodeId;
list_node_t* node = list_find(list, &util_entry);
if(node == NULL) {
clist_node_t *node = clist_find(list, &util_entry);
if (node == NULL)
{
return NULL;
}
else {
return ((NODE_ENTRY*) node->val);
else
{
return ((NODE_ENTRY *)node->val);
}
}
/*****************************************************************************/
/**
* @brief Append a new node entry to the node list
@@ -133,21 +154,24 @@ NODE_ENTRY* L2_GetNodeById(NODE_LIST *list, uint8_t nodeId) {
* Other Error occurred.(Node already exist, memory alloc error ect.)
*
******************************************************************************/
NODE_ENTRY* L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType)
NODE_ENTRY *L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType)
{
ASSERT(list != NULL);
if(L2_isNodeInList(list, nodeId)){
if (L2_isNodeInList(list, nodeId))
{
DBG_WARNING("Node [%d] already exist.\n", nodeId);
return NULL;
}
DBG_INFO("Link layer appending node [%d] to node list.\n", nodeId);
NODE_ENTRY* nodeEntry = (NODE_ENTRY*) malloc(sizeof(NODE_ENTRY));
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = (NODE_ENTRY *)malloc(sizeof(NODE_ENTRY));
if (nodeEntry == NULL)
{
DBG_ERROR("Failed to allocated memory for nodeEntry.\n");
return NULL;
}
list_node_t* node = list_node_new(nodeEntry);
if(node == NULL) {
clist_node_t *node = clist_node_new(nodeEntry);
if (node == NULL)
{
DBG_ERROR("Failed to allocated memory for list node.\n");
free(nodeEntry);
return NULL;
@@ -162,7 +186,7 @@ NODE_ENTRY* L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType
nodeEntry->nodeInfo.speed.z = 0;
nodeEntry->nodeInfo.beamNo = 0;
nodeEntry->ttlCnt = 0;
list_rpush(list, node);
clist_rpush(list, node);
return nodeEntry;
}
@@ -177,16 +201,18 @@ NODE_ENTRY* L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType
* Other Node not exist.
*
******************************************************************************/
int32_t L2_DeleteNodeById(NODE_LIST *list, uint8_t nodeId) {
int32_t L2_DeleteNodeById(NODE_LIST *list, uint8_t nodeId)
{
ASSERT(list != NULL);
util_entry.nodeInfo.nodeId = nodeId;
list_node_t* node = list_find(list, &util_entry);
if(node == NULL) {
clist_node_t *node = clist_find(list, &util_entry);
if (node == NULL)
{
DBG_WARNING("Node [%d] in not in node list, skip deleting process.\n", nodeId);
return SUCCESS;
}
DBG_INFO("Deleting node [%d].\n", nodeId);
list_remove(list, node);
clist_remove(list, node);
return SUCCESS;
}
@@ -201,7 +227,8 @@ int32_t L2_DeleteNodeById(NODE_LIST *list, uint8_t nodeId) {
* false node not in the list
*
******************************************************************************/
bool L2_isNodeInList(NODE_LIST *list, uint8_t nodeId) {
bool L2_isNodeInList(NODE_LIST *list, uint8_t nodeId)
{
ASSERT(list != NULL);
return (L2_GetNodeById(list, nodeId) != NULL);
}
@@ -219,13 +246,16 @@ bool L2_isNodeInList(NODE_LIST *list, uint8_t nodeId) {
*
******************************************************************************/
int32_t L2_GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double* dst) {
int32_t L2_GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double *dst)
{
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL)
{
return FAILURE;
}
else {
else
{
*dst = Coord_Distance(myCoord, nodeEntry->nodeInfo.pos);
return SUCCESS;
}
@@ -243,19 +273,21 @@ int32_t L2_GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double* d
* FAILURE node not exist.
*
******************************************************************************/
int32_t L2_UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos) {
int32_t L2_UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos)
{
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL)
{
return FAILURE;
}
else {
else
{
memcpy(&(nodeEntry->nodeInfo.pos), newPos, sizeof(COORD));
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Get node positions information.
@@ -268,13 +300,16 @@ int32_t L2_UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos) {
* FAILURE node not exist.
*
******************************************************************************/
int32_t L2_GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *pos) {
int32_t L2_GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *pos)
{
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL)
{
return FAILURE;
}
else {
else
{
memcpy(pos, &(nodeEntry->nodeInfo.pos), sizeof(COORD));
}
return SUCCESS;
@@ -292,19 +327,21 @@ int32_t L2_GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *pos) {
* FAILURE node not exist.
*
******************************************************************************/
int32_t L2_UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed) {
int32_t L2_UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed)
{
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL)
{
return FAILURE;
}
else {
else
{
memcpy(&(nodeEntry->nodeInfo.speed), newSpeed, sizeof(COORD));
}
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Get node speed information.
@@ -317,13 +354,16 @@ int32_t L2_UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpee
* FAILURE node not exist.
*
******************************************************************************/
int32_t L2_GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed) {
int32_t L2_GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed)
{
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL)
{
return FAILURE;
}
else {
else
{
memcpy(speed, &(nodeEntry->nodeInfo.speed), sizeof(COORD));
}
return SUCCESS;
@@ -334,19 +374,22 @@ int32_t L2_GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed) {
*
* @param list
* @param nodeId
* @param defl
* @param devi
*
* @return SUCCESS update successfully.
* FAILURE Node not exist.
*
******************************************************************************/
int32_t L2_UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi) {
int32_t L2_UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi)
{
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL)
{
return FAILURE;
}
else {
else
{
nodeEntry->timeDevi = devi;
}
return SUCCESS;
@@ -363,13 +406,16 @@ int32_t L2_UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi
* @return NONE
*
******************************************************************************/
int32_t L2_IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc) {
int32_t L2_IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc)
{
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL)
{
return FAILURE;
}
else {
else
{
nodeEntry->ttlCnt += inc;
}
return SUCCESS;
@@ -386,13 +432,16 @@ int32_t L2_IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc) {
* FAILURE Node not exist.
*
******************************************************************************/
int32_t L2_RstNodeTTL(NODE_LIST *list, uint8_t nodeId) {
int32_t L2_RstNodeTTL(NODE_LIST *list, uint8_t nodeId)
{
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL)
{
return FAILURE;
}
else {
else
{
nodeEntry->ttlCnt = 0;
}
return SUCCESS;
@@ -409,13 +458,16 @@ int32_t L2_RstNodeTTL(NODE_LIST *list, uint8_t nodeId) {
* @return NONE
*
******************************************************************************/
int32_t L2_GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl) {
int32_t L2_GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl)
{
ASSERT(list != NULL);
NODE_ENTRY* nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL) {
NODE_ENTRY *nodeEntry = L2_GetNodeById(list, nodeId);
if (nodeEntry == NULL)
{
return FAILURE;
}
else {
else
{
*ttl = nodeEntry->ttlCnt;
}
return SUCCESS;
@@ -434,24 +486,27 @@ int32_t L2_GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl) {
* Other Error occurred.
*
******************************************************************************/
int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY *, const void *)) {
int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY *, const void *))
{
ASSERT(list != NULL);
int32_t Status;
list_node_t* node;
list_iterator_t* iter = list_iterator_new(list, LIST_HEAD);
if(iter == NULL) {
clist_node_t *node;
clist_iterator_t *iter = clist_iterator_new(list, LIST_HEAD);
if (iter == NULL)
{
DBG_ERROR("Failed to initialize list iteration process.\n");
return EALLOC;
}
while ((node = list_iterator_next(iter)))
while ((node = clist_iterator_next(iter)))
{
Status = operation((NODE_ENTRY*)node->val, param);
if(Status != SUCCESS){
Status = operation((NODE_ENTRY *)node->val, param);
if (Status != SUCCESS)
{
DBG_ERROR("Error occurred when iteratively edit node entry.\n");
break;
}
}
list_iterator_destroy(iter);
clist_iterator_destroy(iter);
return Status;
}
@@ -466,21 +521,23 @@ int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)
* @return SUCCESS
*
******************************************************************************/
int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *)) {
int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *))
{
ASSERT(list != NULL);
list_node_t* node;
list_iterator_t* iter = list_iterator_new(list, LIST_HEAD);
if(iter == NULL) {
clist_node_t *node;
clist_iterator_t *iter = clist_iterator_new(list, LIST_HEAD);
if (iter == NULL)
{
DBG_ERROR("Failed to initialize list iteration process.\n");
return EALLOC;
}
while ((node = list_iterator_next(iter)))
while ((node = clist_iterator_next(iter)))
{
if (condition((NODE_ENTRY*) node->val) == false) {
list_remove(list, node);
if (condition((NODE_ENTRY *)node->val) == false)
{
clist_remove(list, node);
}
}
list_iterator_destroy(iter);
clist_iterator_destroy(iter);
return SUCCESS;
}
+8 -7
View File
@@ -24,18 +24,19 @@
#include "linklayer814_types.h"
#include "geometry/coord.h"
#include "../util/util.h"
#include "../util/list.h"
#include "../util/clist.h"
/************************** Constant Definitions *****************************/
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
typedef struct NODE_LIST_ENTRY {
typedef struct NODE_LIST_ENTRY
{
L2_NODE_INFO nodeInfo;
uint32_t ttlCnt;
int32_t timeDevi;
} NODE_ENTRY;
typedef list_t NODE_LIST;
typedef clist_t NODE_LIST;
/************************** Variable Definitions *****************************/
@@ -44,8 +45,8 @@ int32_t L2_NodeList_Init(NODE_LIST **list);
void L2_NodeList_Clear(NODE_LIST *list);
void L2_NodeList_Destroy(NODE_LIST *list);
uint32_t L2_GetNodeListLen(NODE_LIST *list);
NODE_ENTRY* L2_GetNodeById(NODE_LIST *list, uint8_t nodeId);
NODE_ENTRY* L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType);
NODE_ENTRY *L2_GetNodeById(NODE_LIST *list, uint8_t nodeId);
NODE_ENTRY *L2_AppendNode(NODE_LIST *list, uint8_t nodeId, L2_NODE_TYPE nodeType);
int32_t L2_DeleteNodeById(NODE_LIST *list, uint8_t nodeId);
int32_t L2_UpdateNodePos(NODE_LIST *list, uint8_t nodeId, const COORD *newPos);
bool L2_isNodeInList(NODE_LIST *list, uint8_t nodeId);
@@ -53,11 +54,11 @@ int32_t L2_GetNodePos(NODE_LIST *list, uint8_t nodeId, COORD *newPos);
int32_t L2_UpdateNodeSpeed(NODE_LIST *list, uint8_t nodeId, const COORD *newSpeed);
int32_t L2_GetNodeSpeed(NODE_LIST *list, uint8_t nodeId, COORD *speed);
int32_t L2_UpdateNodeTimeDeviation(NODE_LIST *list, uint8_t nodeId, int32_t devi);
int32_t L2_GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double* dst);
int32_t L2_GetDistance(NODE_LIST *list, COORD myCoord, uint8_t nodeId, double *dst);
int32_t L2_RstNodeTTL(NODE_LIST *list, uint8_t nodeId);
int32_t L2_IncNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t inc);
int32_t L2_GetNodeTTL(NODE_LIST *list, uint8_t nodeId, uint32_t *ttl);
int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY*, const void*));
int32_t L2_IterEditNode(NODE_LIST *list, const void *param, int32_t (*operation)(NODE_ENTRY *, const void *));
int32_t L2_IterDeleteNode(NODE_LIST *list, bool (*condition)(NODE_ENTRY *));
#endif /* NODE_LIST_H_ */
+472
View File
@@ -0,0 +1,472 @@
/*****************************************************************************/
/**
* Description: RTT algorithm.
*
* Author: FanHao
* Date: 2023-12-10 20:43
* LastEditors: FanHao
* LastEditTime: 2023-12-10 20:43
* Revisions: Rev 0.0
* History:
* [2023-12-10]: Initial version, split form time_sync.c
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <string.h>
#include <stdlib.h>
#include "linklayer814.h"
#include "rtt.h"
#include "../time_ctrl/time_ctrl.h"
#include "../phy_ctrl/phy_ctrl.h"
#include "../error.h"
#include "../common.h"
/************************** Constant Definitions *****************************/
#define LIGHT_SPPED_AIR 299702547.0 // m/s
#define LIGHT_SPPED_VAC 299792458.0 // m/s
#define RTT_DOPPLER_NONE UINT32_MAX
const TIME_WORD RTT_TIME_NONE =
{
.int_part = UINT32_MAX,
.frac_part = UINT32_MAX
};
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
static void RTT_StageUpdate(L2_RTT_FSM *rttFsmPtr, L2_RTT_STGE newStage);
static void RTT_GetFrameStart(L2_INST *instPtr, TIME_WORD *tmStamp, L2_TOR_TYPE torType);
/*****************************************************************************/
/**
* @brief Update corrent time-sync for RTT stage
*
* @param scanFsmPtr A pointer to scan net fsm.
* @param newSatge New state.
*
* @return NONE.
*
******************************************************************************/
static void RTT_StageUpdate(L2_RTT_FSM *rttFsmPtr, L2_RTT_STGE newStage)
{
ASSERT(rttFsmPtr != NULL);
ASSERT(newStage >= RTT_NONE_STAGE && newStage <= RTT_RSP2);
DBG_INFO("RTT Stage Update: %d -> %d.\n", rttFsmPtr->rttStage, newStage);
rttFsmPtr->rttStage = newStage;
}
/*****************************************************************************/
/**
* @brief Reset RTT FSM
*
* @param rttFsmPtr a pointer to rtt FSM instance.
*
* @return NONE
*
******************************************************************************/
void RTT_Reset(L2_RTT_FSM *rttFsmPtr)
{
ASSERT(rttFsmPtr != NULL);
memset(&(rttFsmPtr->rttRecord), 0x00, sizeof(RTT_RECORD));
rttFsmPtr->rttStage = RTT_REQ1;
rttFsmPtr->isR1Valid = false;
rttFsmPtr->isR2Valid = false;
rttFsmPtr->isR3Valid = false;
rttFsmPtr->isR4Valid = false;
rttFsmPtr->timeStamp.int_part = 0;
rttFsmPtr->timeStamp.frac_part = 0;
rttFsmPtr->doppler = 0;
}
/*****************************************************************************/
/**
* @brief Destroy RTT FSM, free allocated memory.
*
* @param rttFsmPtr a pointer to rtt FSM instance.
*
* @return NONE
*
******************************************************************************/
void RTT_Destroy(L2_RTT_FSM *rttFsmPtr)
{
free(rttFsmPtr);
}
/*****************************************************************************/
/**
* @brief Get the frame start time. If torType == L2_TOR_TX, get the next
* slot start time, if torType == L2_TOR_RX get last frame start
* time.
*
* @param instPtr a pointer to linklayer layer instance
* @param tmStamp a pointer to store frame start time
* @param torType tx/rx mode
*
* @return NONE
*
******************************************************************************/
void RTT_GetFrameStart(L2_INST *instPtr, TIME_WORD *tmStamp, L2_TOR_TYPE torType)
{
ASSERT(instPtr != NULL);
ASSERT(tmStamp != NULL);
// Get the next frame start time
if (torType == L2_TOR_TX)
{
tmStamp->int_part = L2_GetNextFrameNum(instPtr) * L2_SLOTS_PER_FRAME + L2_GetNextSlotNum(instPtr);
tmStamp->frac_part = 0;
}
// Get the last reiceive frame start time
else if (torType == L2_TOR_RX)
{
PHY_INST *phyRef = instPtr->config.phyInstPtr;
TIME_WORD timeStamp;
int64_t timeDiff;
Phy_GetLastReceivedFrameSyncTimeStamp(phyRef, &timeStamp);
timeDiff = (uint64_t)timeStamp.frac_part;
timeDiff += ((uint64_t)timeStamp.int_part) * TIME_FRAC_MAX;
Phy_GetLastReceivedSlotStartTimeStamp(phyRef, tmStamp);
timeDiff -= ((uint64_t)tmStamp->int_part) * TIME_FRAC_MAX;
timeDiff -= (uint64_t)tmStamp->frac_part;
timeDiff = (int64_t)Phy_GetTimeComp(L2_L2frame2L1frame(L2_GetLastFrameType(instPtr))) - timeDiff;
if (timeDiff < 0)
{
timeDiff += TIME_FRAC_MAX;
tmStamp->int_part--;
_nop_();
}
tmStamp->frac_part = (TIME_FRAC)timeDiff;
}
else
{
*tmStamp = RTT_TIME_NONE;
DBG_ERROR("Unexpected tx/rx mode, setting dummy values.\n");
}
}
/*****************************************************************************/
/**
* @brief Initialize RTT FSM, allocate memory for FSM instance.
*
* @param rttFsmPtr
*
* @return SUCCESS Initialization successful.
* EMAC_MEMORY_ALLOC_ERROR Memory allocate error.
*
******************************************************************************/
int32_t RTT_Init(L2_RTT_FSM **rttFsmPtr)
{
(*rttFsmPtr) = (L2_RTT_FSM *)malloc(sizeof(L2_RTT_FSM));
if (*rttFsmPtr == NULL)
{
free(*rttFsmPtr);
return EALLOC;
}
RTT_Reset(*rttFsmPtr);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Update RTT FSM accordingly.
*
* @param instPtr a pointer to linklayer layer instance
* @param torType tx/rx mode type
*
* @return SUCCESS
* error code
*
******************************************************************************/
int32_t RTT_FsmUpdate(L2_INST *instPtr, L2_TOR_TYPE torType)
{
ASSERT(instPtr != NULL);
L2_RTT_FSM *rttFsmPtr = L2_GetRttFsm(instPtr);
RTT_RECORD *rttRecord = &(rttFsmPtr->rttRecord);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
DBG_INFO("-------- RTT FSM Update --------\n");
// Stage trans
// For Head Node: Tx->Rx->Tx->Rx
if (L2_GetNodeType(instPtr) == L2_NODE_HEAD)
{
switch (rttFsmPtr->rttStage)
{
case RTT_REQ1:
if (torType == L2_TOR_TX)
{
DBG_INFO("Prepare data for RTT REQ-1\n");
// Update Tt1
RTT_GetFrameStart(instPtr, &(rttRecord->Tt1), torType);
DBG_INFO("Tt1-timeL:%u.\n", rttRecord->Tt1.int_part);
DBG_INFO("Tt1-timeH:%u.\n", rttRecord->Tt1.frac_part);
// Prepare data for sending...
rttFsmPtr->timeStamp = rttRecord->Tt1;
rttFsmPtr->doppler = RTT_DOPPLER_NONE;
RTT_StageUpdate(rttFsmPtr, RTT_RSP1);
}
else
{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP1:
if (torType == L2_TOR_RX)
{
if (L2_isDataAvail(instPtr) == true)
{
DBG_INFO("RTT RSP-1 have been received.\n");
DBG_INFO("Preparing data for RTT REQ-2.\n");
rttFsmPtr->isR2Valid = true;
// Update doppler
rttRecord->dopplerR2 = (int32_t)Phy_GetFreqEst(phyRef);
// Update Tr2
RTT_GetFrameStart(instPtr, &(rttRecord->Tr2), torType);
// Calculate TroundA
TimeCtrl_CalculateTimeGap(&(rttRecord->Tt1), &(rttRecord->Tr2), &(rttRecord->TroundA));
}
else
{
DBG_WARNING("RTT RSP-1 had not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set Tr2 dopplerR2 and TroundA to dummy value.\n");
rttFsmPtr->isR2Valid = false;
rttRecord->dopplerR2 = RTT_DOPPLER_NONE;
rttRecord->Tr2 = RTT_TIME_NONE;
rttRecord->TroundA = RTT_TIME_NONE;
}
DBG_INFO("dopplerR2:%d.\n", rttRecord->dopplerR2);
DBG_INFO("Tr2-timeL:%u.\n", rttRecord->Tr2.frac_part);
DBG_INFO("Tr2-timeH:%u.\n", rttRecord->Tr2.int_part);
DBG_INFO("TroundA-timeL:%u.\n", rttRecord->TroundA.frac_part);
DBG_INFO("TroundA-timeH:%u.\n", rttRecord->TroundA.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_REQ2);
}
else
{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_REQ2:
if (torType == L2_TOR_TX)
{
DBG_INFO("Prepare data for RTT REQ-2\n");
// Update Tt3
RTT_GetFrameStart(instPtr, &(rttRecord->Tt3), torType);
if (rttFsmPtr->isR2Valid)
{
// Calculate reply A
TimeCtrl_CalculateTimeGap(&(rttRecord->Tt3), &(rttRecord->Tr2), &(rttRecord->TreplyA));
}
else
{
DBG_WARNING("RTT RSP-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set TreplyA to dummy value.\n");
rttRecord->TreplyA = RTT_TIME_NONE;
}
DBG_INFO("Tt3-timeL:%u.\n", rttRecord->Tt3.frac_part);
DBG_INFO("Tt3-timeH:%u.\n", rttRecord->Tt3.int_part);
DBG_INFO("TreplyA-timeL:%u.\n", rttRecord->TreplyA.frac_part);
DBG_INFO("TreplyA-timeH:%u.\n", rttRecord->TreplyA.int_part);
// Prepare data for sending.
rttFsmPtr->timeStamp = rttRecord->TroundA;
rttFsmPtr->doppler = rttRecord->dopplerR2;
RTT_StageUpdate(rttFsmPtr, RTT_RSP2);
}
else
{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP2:
if (torType == L2_TOR_RX)
{
if (L2_isDataAvail(instPtr) == true)
{
DBG_INFO("RTT RSP-2 have been received.\n");
rttFsmPtr->isR4Valid = true;
// Update doppler
double doppler = Phy_GetFreqEst(phyRef);
rttRecord->dopplerR2 = (int32_t)doppler;
// Update Tr4
RTT_GetFrameStart(instPtr, &(rttRecord->Tr4), torType);
// Calculate TroundA
TimeCtrl_CalculateTimeGap(&(rttRecord->Tt3), &(rttRecord->Tr4), &(rttRecord->TroundA));
}
else
{
DBG_WARNING("RTT RSP-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set Tr4 dopplerR4 and TroundA to dummy value.\n");
rttFsmPtr->isR4Valid = false;
rttRecord->dopplerR4 = RTT_DOPPLER_NONE;
rttRecord->Tr4 = RTT_TIME_NONE;
rttRecord->TroundA = RTT_TIME_NONE;
}
DBG_INFO("dopplerR4:%d.\n", rttRecord->dopplerR4);
DBG_INFO("Tr4-timeL:%u.\n", rttRecord->Tr4.frac_part);
DBG_INFO("Tr4-timeH:%u.\n", rttRecord->Tr4.int_part);
DBG_INFO("TroundA-timeL:%u.\n", rttRecord->TroundA.frac_part);
DBG_INFO("TroundA-timeH:%u.\n", rttRecord->TroundA.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_REQ1);
DBG_INFO("RTT procedure end...\n");
}
else
{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
default:
DBG_ERROR("Unexpected RTT FSM stage [%d].\n", rttFsmPtr->rttStage);
break;
}
}
// For Member Node: Rx->Tx->Rx->Tx
else
{
switch (rttFsmPtr->rttStage)
{
case RTT_REQ1:
if (torType == L2_TOR_RX)
{
if (L2_isDataAvail(instPtr) == true)
{
DBG_INFO("RTT REQ-1 have been received.\n");
DBG_INFO("Preparing data for RTT RSP-1.\n");
rttFsmPtr->isR2Valid = true;
// Update doppler
rttRecord->dopplerR2 = (int32_t)Phy_GetFreqEst(phyRef);
// Update Tr1
RTT_GetFrameStart(instPtr, &(rttRecord->Tr1), torType);
}
else
{
DBG_WARNING("RTT REQ-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set dopplerR1 and Tr1 to dummy value.\n");
rttFsmPtr->isR1Valid = false;
rttRecord->dopplerR1 = RTT_DOPPLER_NONE;
rttRecord->Tr1 = RTT_TIME_NONE;
}
DBG_INFO("dopplerR1:%d.\n", rttRecord->dopplerR1);
DBG_INFO("Tr1-timeL:%u.\n", rttRecord->Tr1.frac_part);
DBG_INFO("Tr1-timeH:%u.\n", rttRecord->Tr1.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_RSP1);
}
else
{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP1:
if (torType == L2_TOR_TX)
{
DBG_INFO("Prepare data for RTT RSP-1\n");
// Update Tt2
RTT_GetFrameStart(instPtr, &(rttRecord->Tt2), torType);
if (rttFsmPtr->isR1Valid)
{
// Calculate reply B
TimeCtrl_CalculateTimeGap(&(rttRecord->Tr1), &(rttRecord->Tt2), &(rttRecord->TreplyB));
}
else
{
rttRecord->TreplyB = RTT_TIME_NONE;
DBG_WARNING("RTT REQ-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set ReplayB to dummy value.\n");
}
DBG_INFO("Tt2-timeL:%u.\n", rttRecord->Tt2.frac_part);
DBG_INFO("Tt2-timeH:%u.\n", rttRecord->Tt2.int_part);
DBG_INFO("TreplyB-timeL:%u.\n", rttRecord->TreplyB.frac_part);
DBG_INFO("TreplyB-timeH:%u.\n", rttRecord->TreplyB.int_part);
// Prepare data for sending.
rttFsmPtr->timeStamp = rttRecord->TreplyB;
rttFsmPtr->doppler = rttRecord->dopplerR1;
RTT_StageUpdate(rttFsmPtr, RTT_REQ2);
}
else
{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_REQ2:
if (torType == L2_TOR_RX)
{
if (L2_isDataAvail(instPtr) == true)
{
DBG_INFO("RTT REQ-2 have been received.\n");
DBG_INFO("Preparing data for RTT RSP-2.\n");
rttFsmPtr->isR3Valid = true;
// Update doppler
rttRecord->dopplerR2 = (int32_t)Phy_GetFreqEst(phyRef);
// Update Tr3
RTT_GetFrameStart(instPtr, &(rttRecord->Tr3), torType);
// Calculate TroundB
TimeCtrl_CalculateTimeGap(&(rttRecord->Tt2), &(rttRecord->Tr3), &(rttRecord->TroundB));
}
else
{
DBG_WARNING("RTT REQ-2 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set dopplerR3 and ReplayB to dummy value.\n");
rttFsmPtr->isR3Valid = false;
rttRecord->dopplerR3 = RTT_DOPPLER_NONE;
rttRecord->TroundB = RTT_TIME_NONE;
}
DBG_INFO("dopplerR3:%d.\n", rttRecord->dopplerR3);
DBG_INFO("Tr3-timeL:%u.\n", rttRecord->Tr3.frac_part);
DBG_INFO("Tr3-timeH:%u.\n", rttRecord->Tr3.int_part);
DBG_INFO("TroundB-timeL:%u.\n", rttRecord->TroundB.frac_part);
DBG_INFO("TroundB-timeH:%u.\n", rttRecord->TroundB.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_RSP2);
}
else
{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP2:
if (torType == L2_TOR_TX)
{
DBG_INFO("Prepare data for RTT RSP-2\n");
// Update Tt4
RTT_GetFrameStart(instPtr, &(rttRecord->Tt4), torType);
if (rttFsmPtr->isR3Valid)
{
// Calculate reply B
TimeCtrl_CalculateTimeGap(&(rttRecord->Tr3), &(rttRecord->Tt4), &(rttRecord->TreplyB));
// TODO: implement a time adjustment.
}
else
{
DBG_WARNING("RTT REQ-2 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set ReplayB to dummy value.\n");
rttRecord->TreplyB = RTT_TIME_NONE;
}
DBG_INFO("Tt4-timeL:%u.\n", rttRecord->Tt4.frac_part);
DBG_INFO("Tt4-timeH:%u.\n", rttRecord->Tt4.int_part);
DBG_INFO("TreplyB-timeL:%u.\n", rttRecord->TreplyB.frac_part);
DBG_INFO("TreplyB-timeH:%u.\n", rttRecord->TreplyB.int_part);
// Prepare data for sending.
rttFsmPtr->timeStamp = rttRecord->TreplyB;
rttFsmPtr->doppler = rttRecord->dopplerR3;
RTT_StageUpdate(rttFsmPtr, RTT_REQ1);
DBG_INFO("RTT procedure end...\n");
}
else
{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
default:
DBG_ERROR("Unexpected RTT FSM stage [%d].\n", rttFsmPtr->rttStage);
break;
}
}
return SUCCESS;
}
+10 -7
View File
@@ -1,18 +1,18 @@
/*****************************************************************************/
/**
* Description: A simplified version of timesync for datalink 814 (Dijian)
*
*
* Date: 2021-12-04 16:32
* LastEditors: Fan Hao
* LastEditTime: 2022-07-06 16:32
* Revisions: Rev 0.0
* History:
* History:
* [2022-07-06]: Initial version.
* [2021-12-04]: Initial version.
*
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
#ifndef RTT_H_
@@ -29,7 +29,8 @@
/**************************** Type Definitions *******************************/
// TODO: Multi-node RTT
typedef struct {
typedef struct
{
TIME_WORD Tt1;
TIME_WORD Tr1;
TIME_WORD Tt2;
@@ -48,7 +49,8 @@ typedef struct {
TIME_WORD TreplyB;
} RTT_RECORD;
typedef enum {
typedef enum
{
RTT_NONE_STAGE = 0,
RTT_REQ1 = 1,
RTT_RSP1 = 2,
@@ -56,7 +58,8 @@ typedef enum {
RTT_RSP2 = 4, // Rtt Stages
} L2_RTT_STGE;
typedef struct {
typedef struct
{
L2_RTT_STGE rttStage;
bool isR1Valid;
bool isR2Valid;
+116 -71
View File
@@ -8,7 +8,7 @@
* Revisions: Rev 0.0
* History:
* [2023-12-21]: Initial version.
*
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
@@ -20,7 +20,7 @@
#include "linklayer814.h"
#include "linklayer814_types.h"
#include "../error.h"
#include "../util/list.h"
#include "../util/clist.h"
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
@@ -29,22 +29,38 @@ static L2_SCHD_EVENT util_schdevent;
/**
* @brief helper function to free schedule events.
*/
static void schdevent_free(void* val){
if(val == NULL) {
static void schdevent_free(void *val)
{
if (val == NULL)
{
return;
}
free(((L2_SCHD_EVENT*)val)->l2Event.msg);
free(((L2_SCHD_EVENT *)val)->l2Event.msg);
free(val);
}
/**
* @brief helper function to match events by ids.
*/
static bool schdevent_match(void* a, void* b){
static int8_t schdevent_compare(void *a, void *b)
{
ASSERT(a == NULL);
ASSERT(b != NULL);
return (((L2_SCHD_EVENT*)a)->eventId
== ((L2_SCHD_EVENT*)b)->eventId);
register uint32_t idA, idB;
idA = ((L2_SCHD_EVENT *)a)->eventId;
idB = ((L2_SCHD_EVENT *)b)->eventId;
if (idA == idB)
{
return 0;
}
else if (idA < idB)
{
return -1;
}
else
{
return 1;
}
}
/*****************************************************************************/
@@ -56,27 +72,30 @@ static bool schdevent_match(void* a, void* b){
* @return SUCCESS
*
******************************************************************************/
int32_t L2_CreateSchedEventPool(L2_SCHD_POOL** schdPool) {
int32_t L2_CreateSchedEventPool(L2_SCHD_POOL **schdPool)
{
(*schdPool) = malloc(sizeof(L2_SCHD_POOL));
if(*schdPool == NULL) {
if (*schdPool == NULL)
{
DBG_ERROR("Failed to allocated memory for schdPool.\n");
return EALLOC;
}
(*schdPool)->schdList = list_new();
if((*schdPool)->schdList == NULL) {
(*schdPool)->schdList = clist_new();
if ((*schdPool)->schdList == NULL)
{
DBG_ERROR("Failed to allocated memory for schdPool->schdList.\n");
free(*schdPool);
return EALLOC;
}
(*schdPool)->schdList->free = schdevent_free;
(*schdPool)->schdList->match = schdevent_match;
(*schdPool)->schdList->compare = schdevent_compare;
(*schdPool)->envCnt = 0;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Clear schedule event pool, delete all events in pool and
* @brief Clear schedule event pool, delete all events in pool and
* free allocated memory.
*
* @param schdPool a pointer to schedule pool instance.
@@ -84,9 +103,10 @@ int32_t L2_CreateSchedEventPool(L2_SCHD_POOL** schdPool) {
* @return SUCCESS
*
******************************************************************************/
void L2_ClearSchedEventPool(L2_SCHD_POOL* schdPool) {
void L2_ClearSchedEventPool(L2_SCHD_POOL *schdPool)
{
ASSERT(schdPool != NULL);
list_clear(schdPool->schdList);
clist_clear(schdPool->schdList);
schdPool->envCnt = 0;
}
@@ -99,11 +119,13 @@ void L2_ClearSchedEventPool(L2_SCHD_POOL* schdPool) {
* @return SUCCESS
*
******************************************************************************/
void L2_DestroySchedEventPool(L2_SCHD_POOL* schdPool) {
if(schdPool == NULL) {
void L2_DestroySchedEventPool(L2_SCHD_POOL *schdPool)
{
if (schdPool == NULL)
{
return;
}
list_destroy(schdPool->schdList);
clist_destroy(schdPool->schdList);
free(schdPool);
}
@@ -119,32 +141,36 @@ void L2_DestroySchedEventPool(L2_SCHD_POOL* schdPool) {
* Pointer to schedule event.
*
******************************************************************************/
L2_SCHD_EVENT* L2_CreatNewSchdEvent(L2_SCHD_POOL* schdPool, L2_EVENT_TYPE event, bool isVolatile){
L2_SCHD_EVENT *L2_CreatNewSchdEvent(L2_SCHD_POOL *schdPool, L2_EVENT_TYPE event, bool isVolatile)
{
ASSERT(schdPool != NULL);
if(event < L2_EV_SCAN_PROC_DONE || event > L2_ROUTINE_UPDATE){
if (event < L2_EV_SCAN_PROC_DONE || event > L2_ROUTINE_UPDATE)
{
DBG_ERROR("Unknown event type: %d.\n", event);
return NULL;
}
L2_SCHD_EVENT* schdEvent = (L2_SCHD_EVENT*)malloc(sizeof(L2_SCHD_EVENT));
if(schdEvent == NULL){
L2_SCHD_EVENT *schdEvent = (L2_SCHD_EVENT *)malloc(sizeof(L2_SCHD_EVENT));
if (schdEvent == NULL)
{
DBG_ERROR("Failed to allocate schedule event.\n");
return NULL;
}
list_node_t *node = list_node_new(schdEvent);
if(node == NULL) {
clist_node_t *node = clist_node_new(schdEvent);
if (node == NULL)
{
DBG_ERROR("Failed to allocate schedule event list node.\n");
free(schdEvent);
return NULL;
}
schdEvent->eventId = schdPool->envCnt++;
schdEvent->ocurrCnt = 0;
schdEvent->occurCnt = 0;
schdEvent->l2Event.event = event;
schdEvent->l2Event.msg = NULL;
schdEvent->isSchd = false;
schdEvent->isVolatile = isVolatile;
schdEvent->schdSlot = L2_SLOTNO_NONE;
schdEvent->schdFrame = L2_FRAMENO_NONE;
list_rpush(schdPool->schdList, node);
clist_rpush(schdPool->schdList, node);
return schdEvent;
}
@@ -159,20 +185,22 @@ L2_SCHD_EVENT* L2_CreatNewSchdEvent(L2_SCHD_POOL* schdPool, L2_EVENT_TYPE event,
* Pointer to the schedule event.
*
******************************************************************************/
L2_SCHD_EVENT* L2_GetEventById(L2_SCHD_POOL* schdPool, uint32_t id) {
L2_SCHD_EVENT *L2_GetEventById(L2_SCHD_POOL *schdPool, uint32_t id)
{
ASSERT(schdPool != NULL);
util_schdevent.eventId = id;
list_node_t* node = list_find(schdPool->schdList, &util_schdevent);
if(node != NULL) {
clist_node_t *node = clist_find(schdPool->schdList, &util_schdevent);
if (node != NULL)
{
DBG_WARNING("Event with id=%d, dose not exist.\n", id);
return NULL;
}
return ((L2_SCHD_EVENT*) node->val);
return ((L2_SCHD_EVENT *)node->val);
}
/*****************************************************************************/
/**
* @brief Delete a schedule event, remove the event from event pool,
* @brief Delete a schedule event, remove the event from event pool,
* release memory.
*
* @param schdPool a pointer to schedule pool instance.
@@ -182,15 +210,17 @@ L2_SCHD_EVENT* L2_GetEventById(L2_SCHD_POOL* schdPool, uint32_t id) {
* error code
*
******************************************************************************/
int32_t L2_DeleteSchdEventById(L2_SCHD_POOL* schdPool, uint32_t id) {
int32_t L2_DeleteSchdEventById(L2_SCHD_POOL *schdPool, uint32_t id)
{
ASSERT(schdPool != NULL);
util_schdevent.eventId = id;
list_node_t* node = list_find(schdPool->schdList, &util_schdevent);
if(node != NULL) {
clist_node_t *node = clist_find(schdPool->schdList, &util_schdevent);
if (node != NULL)
{
DBG_ERROR("Event with id=%d, dose not exist.\n", id);
return EIGNORE;
}
list_remove(schdPool->schdList, node);
clist_remove(schdPool->schdList, node);
return SUCCESS;
}
@@ -207,20 +237,23 @@ int32_t L2_DeleteSchdEventById(L2_SCHD_POOL* schdPool, uint32_t id) {
* SUCCESS
*
******************************************************************************/
int32_t L2_ScheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t frameNum, uint32_t slotNum){
int32_t L2_ScheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNum, uint32_t slotNum)
{
ASSERT(schdEvent != NULL);
if(L2_isEventScheduled(schdEvent) == true){
if (L2_isEventScheduled(schdEvent) == true)
{
DBG_ERROR("Event %d has already been scheduled.\n", schdEvent->eventId);
return FAILURE;
}
if(frameNum <= L2_GetCurrentFrameNum(instPtr) && slotNum < L2_GetCurrentSlotNum(instPtr)){
if (frameNum <= L2_GetCurrentFrameNum(instPtr) && slotNum < L2_GetCurrentSlotNum(instPtr))
{
DBG_ERROR("Cannot schedule event %d to the past(current: [%u-%u], schedule: [%u-%u]).\n",
schdEvent->eventId, L2_GetCurrentFrameNum(instPtr), L2_GetCurrentSlotNum(instPtr), frameNum, slotNum);
schdEvent->eventId, L2_GetCurrentFrameNum(instPtr), L2_GetCurrentSlotNum(instPtr), frameNum, slotNum);
return FAILURE;
}
DBG_INFO("Schedule event (type:%d) [%u] at %u-%u.\n",
schdEvent->l2Event.event, schdEvent->eventId,
frameNum, slotNum);
DBG_INFO("Schedule event (type:%d) [%u] at %u-%u.\n",
schdEvent->l2Event.event, schdEvent->eventId,
frameNum, slotNum);
schdEvent->isSchd = true;
schdEvent->schdFrame = frameNum;
schdEvent->schdSlot = slotNum;
@@ -239,14 +272,16 @@ int32_t L2_ScheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t
* SUCCESS
*
******************************************************************************/
int32_t L2_ScheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t numSlots){
int32_t L2_ScheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots)
{
ASSERT(schdEvent != NULL);
if(L2_isEventScheduled(schdEvent) == true){
if (L2_isEventScheduled(schdEvent) == true)
{
DBG_ERROR("Event %d has already been scheduled.\n", schdEvent->eventId);
return FAILURE;
}
uint32_t frameNum = L2_GetCurrentFrameNum(instPtr) + (numSlots/L2_SLOTS_PER_FRAME);
uint32_t slotNum = L2_GetCurrentSlotNum(instPtr) + (numSlots%L2_SLOTS_PER_FRAME);
uint32_t frameNum = L2_GetCurrentFrameNum(instPtr) + (numSlots / L2_SLOTS_PER_FRAME);
uint32_t slotNum = L2_GetCurrentSlotNum(instPtr) + (numSlots % L2_SLOTS_PER_FRAME);
return L2_ScheduleEventAt(instPtr, schdEvent, frameNum, slotNum);
}
@@ -263,9 +298,11 @@ int32_t L2_ScheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32
* SUCCESS
*
******************************************************************************/
int32_t L2_RescheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t frameNum, uint32_t slotNum){
int32_t L2_RescheduleEventAt(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t frameNum, uint32_t slotNum)
{
ASSERT(schdEvent != NULL);
if(schdEvent->isSchd == false){
if (schdEvent->isSchd == false)
{
DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId);
}
schdEvent->isSchd = false;
@@ -284,15 +321,16 @@ int32_t L2_RescheduleEventAt(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_
* SUCCESS
*
******************************************************************************/
int32_t L2_RescheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint32_t numSlots){
int32_t L2_RescheduleEventAfter(L2_INST *instPtr, L2_SCHD_EVENT *schdEvent, uint32_t numSlots)
{
ASSERT(schdEvent != NULL);
if(schdEvent->isSchd == false){
if (schdEvent->isSchd == false)
{
DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId);
}
return L2_ScheduleEventAfter(instPtr, schdEvent, numSlots);
}
/*****************************************************************************/
/**
* @brief Check and excute schedule event in event pool illiterate.
@@ -302,37 +340,40 @@ int32_t L2_RescheduleEventAfter(L2_INST* instPtr, L2_SCHD_EVENT* schdEvent, uint
* @return NONE.
*
******************************************************************************/
void L2_EventPoolHandler(L2_INST* instPtr){
void L2_EventPoolHandler(L2_INST *instPtr)
{
ASSERT(instPtr != NULL);
list_node_t* node;
L2_SCHD_EVENT* event;
clist_node_t *node;
L2_SCHD_EVENT *event;
L2_SCHD_POOL *pool = instPtr->schdEventPool;
list_iterator_t* iter = list_iterator_new(pool->schdList, LIST_HEAD);
clist_iterator_t *iter = clist_iterator_new(pool->schdList, LIST_HEAD);
if (iter == NULL)
{
DBG_ERROR("Failed to initialize schedule event pool iteration.\n");
return;
}
while (iter->next != NULL)
while ((node = clist_iterator_next(iter)))
{
node = list_iterator_next(iter);
event = (L2_SCHD_EVENT*)node->val;
if(L2_isEventScheduled(event)){
if(event->schdFrame == L2_GetCurrentFrameNum(instPtr)
&& event->schdSlot == L2_GetCurrentSlotNum(instPtr)){
event = (L2_SCHD_EVENT *)node->val;
if (L2_isEventScheduled(event))
{
if (event->schdFrame == L2_GetCurrentFrameNum(instPtr) && event->schdSlot == L2_GetCurrentSlotNum(instPtr))
{
DBG_INFO("Asserting scheduled event [%d].\n", event->eventId);
AssertL2Event(instPtr, &(event->l2Event));
if(event->isVolatile == true) {
if (event->isVolatile == true)
{
DBG_INFO("Deleting scheduled event [%d], since it is volatile.\n", event->eventId);
list_remove(pool->schdList, node);
clist_remove(pool->schdList, node);
}
else {
event->ocurrCnt++;
else
{
event->occurCnt++;
}
}
}
}
list_iterator_destroy(iter);
clist_iterator_destroy(iter);
}
/*****************************************************************************/
@@ -346,7 +387,8 @@ void L2_EventPoolHandler(L2_INST* instPtr){
* error code.
*
******************************************************************************/
inline void L2_SchdEventAppendMsg(L2_SCHD_EVENT* schdEvent, void* msg){
inline void L2_SchdEventAppendMsg(L2_SCHD_EVENT *schdEvent, void *msg)
{
ASSERT(schdEvent != NULL);
schdEvent->l2Event.msg = msg;
}
@@ -360,9 +402,11 @@ inline void L2_SchdEventAppendMsg(L2_SCHD_EVENT* schdEvent, void* msg){
* @return SUCCESS.
*
******************************************************************************/
inline int32_t L2_CancelEvent(L2_SCHD_EVENT* schdEvent){
inline int32_t L2_CancelEvent(L2_SCHD_EVENT *schdEvent)
{
ASSERT(schdEvent != NULL);
if(schdEvent->isSchd == false){
if (schdEvent->isSchd == false)
{
DBG_WARNING("Event %d has not been scheduled yet.\n", schdEvent->eventId);
}
schdEvent->isSchd = false;
@@ -379,7 +423,8 @@ inline int32_t L2_CancelEvent(L2_SCHD_EVENT* schdEvent){
* false.
*
******************************************************************************/
inline bool L2_isEventScheduled(const L2_SCHD_EVENT* schdEvent){
inline bool L2_isEventScheduled(const L2_SCHD_EVENT *schdEvent)
{
ASSERT(schdEvent != NULL);
return schdEvent->isSchd;
}
+18 -16
View File
@@ -8,7 +8,7 @@
* Revisions: Rev 0.0
* History:
* [2023-12-21]: Initial version.
*
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
@@ -21,18 +21,19 @@
#include <stdlib.h>
#include "linklayer814_types.h"
#include "../error.h"
#include "../util/list.h"
#include "../util/clist.h"
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/** @name L2 event
* A definition of L2 event instance.
*/
typedef struct {
typedef struct
{
bool isSchd;
bool isVolatile;
L2_EVENT l2Event;
uint32_t eventId;
uint32_t ocurrCnt;
uint32_t occurCnt;
uint32_t schdFrame;
uint32_t schdSlot;
} L2_SCHD_EVENT;
@@ -40,24 +41,25 @@ typedef struct {
/** @name L2 event
* A definition of L2 event instance.
*/
typedef struct {
list_t* schdList;
typedef struct
{
clist_t *schdList;
uint32_t envCnt;
} L2_SCHD_POOL;
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
// Scheduling Event
int32_t L2_CreateSchedEventPool(L2_SCHD_POOL** schdPool);
void L2_ClearSchedEventPool(L2_SCHD_POOL* schdPool);
void L2_DestroySchedEventPool(L2_SCHD_POOL* schdPool);
int32_t L2_CreateSchedEventPool(L2_SCHD_POOL **schdPool);
void L2_ClearSchedEventPool(L2_SCHD_POOL *schdPool);
void L2_DestroySchedEventPool(L2_SCHD_POOL *schdPool);
L2_SCHD_EVENT* L2_CreatNewSchdEvent(L2_SCHD_POOL* schdPool, L2_EVENT_TYPE event, bool isVolatile);
L2_SCHD_EVENT* L2_GetEventById(L2_SCHD_POOL* schdPool, uint32_t id);
int32_t L2_DeleteSchdEventById(L2_SCHD_POOL* schdPool, uint32_t id);
L2_SCHD_EVENT *L2_CreatNewSchdEvent(L2_SCHD_POOL *schdPool, L2_EVENT_TYPE event, bool isVolatile);
L2_SCHD_EVENT *L2_GetEventById(L2_SCHD_POOL *schdPool, uint32_t id);
int32_t L2_DeleteSchdEventById(L2_SCHD_POOL *schdPool, uint32_t id);
void L2_SchdEventAppendMsg(L2_SCHD_EVENT* schdEvent, void* msg);
bool L2_isEventScheduled(const L2_SCHD_EVENT* schdEvent);
int32_t L2_CancelEvent(L2_SCHD_EVENT* schdEvent);
void L2_SchdEventAppendMsg(L2_SCHD_EVENT *schdEvent, void *msg);
bool L2_isEventScheduled(const L2_SCHD_EVENT *schdEvent);
int32_t L2_CancelEvent(L2_SCHD_EVENT *schdEvent);
#endif //SCHDEVENT_H_
#endif // SCHDEVENT_H_
+24 -437
View File
@@ -1,56 +1,43 @@
/*****************************************************************************/
/**
* Description: Time sync implementation file.
*
*
* Author: Author's name
* Date: 2021-12-04 16:32
* LastEditors: FanHao
* LastEditTime: 2022-07-10 20:43
* Revisions: Rev 0.0
* History:
* 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
*
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <string.h>
#include <stdlib.h>
#include "linklayer814.h"
#include "rtt.h"
#include "../time_ctrl/time_ctrl.h"
#include "../phy_ctrl/phy_ctrl.h"
#include "../error.h"
#include "../common.h"
/************************** Constant Definitions *****************************/
#define LIGHT_SPPED_AIR 299702547.0 // m/s
#define LIGHT_SPPED_VAC 299792458.0 // m/s
#define RTT_DOPPLER_NONE UINT32_MAX
const TIME_WORD RTT_TIME_NONE = {
.int_part = UINT32_MAX,
.frac_part = UINT32_MAX
};
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
static void RTT_StageUpdate(L2_RTT_FSM* rttFsmPtr, L2_RTT_STGE newStage);
static void RTT_GetFrameStart(L2_INST* instPtr, TIME_WORD *tmStamp, L2_TOR_TYPE torType);
void RTT_CalculateTimeGap(const TIME_WORD *tmA, const TIME_WORD *tmB, TIME_WORD *tRound);
/*****************************************************************************/
/**
* @brief a slot alignment, base on physical layer information.
*
* @param instPtr a pointer to linklayer layer instance
* @param frameNum
* @param slotNum
* @param frameNum
* @param slotNum
*
* @return SUCCESS Initialize successfully.
* FAILURE Initialization failed, allocate memory fail or initial
@@ -58,437 +45,37 @@ void RTT_CalculateTimeGap(const TIME_WORD *tmA, const TIME_WORD *tmB, TIME_WORD
*
******************************************************************************/
// TODO: Check
int32_t L2_TimeAlign(L2_INST* instPtr, uint32_t frameNum, uint32_t slotNum){
int32_t L2_TimeAlign(L2_INST *instPtr, uint32_t frameNum, uint32_t slotNum, bool relative)
{
L1_FRAME_TYPE lastRecvdFrame;
lastRecvdFrame = Phy_GetLastRecvFrameType(instPtr->config.phyInstPtr);
if(lastRecvdFrame != L1_NONE_FRAME){
if (lastRecvdFrame == L1_NONE_FRAME)
{
DBG_ERROR("Invalid TimeAlign operation, no frame was received.");
return EIGNORE;
}
DBG_INFO("Starting TimeAlign operation...\n");
// read nextSendTime from physical layer
uint64_t currTime, expctTime;
int64_t timeDiff;
TIME_WORD timeStamp, slotTimerAdjmet;
expctTime = ((uint64_t)(frameNum*L2_SLOTS_PER_FRAME + slotNum))*COUNTE_FRAC_MAX;
expctTime = ((uint64_t)(frameNum * L2_SLOTS_PER_FRAME + slotNum)) * TIME_FRAC_MAX;
expctTime += Phy_GetTimeComp(lastRecvdFrame);
Phy_GetFrameSyncTimeStamp(instPtr->config.phyInstPtr, &timeStamp);
if (relative)
{
expctTime += (uint64_t)instPtr->netStartTime * L2_SLOTS_PER_FRAME * TIME_FRAC_MAX;
}
Phy_GetLastReceivedFrameSyncTimeStamp(instPtr->config.phyInstPtr, &timeStamp);
currTime = (uint64_t)timeStamp.frac_part;
currTime += ((uint64_t)timeStamp.int_part) * COUNTE_FRAC_MAX;
currTime += ((uint64_t)timeStamp.int_part) * TIME_FRAC_MAX;
timeDiff = (int64_t)(expctTime - currTime);
slotTimerAdjmet.int_part = (uint32_t)(timeDiff / COUNTE_FRAC_MAX);
slotTimerAdjmet.frac_part = (uint32_t)(timeDiff % COUNTE_FRAC_MAX);
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);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Update corrent time-sync for RTT stage
*
* @param scanFsmPtr A pointer to scan net fsm.
* @param newSatge New state.
*
* @return NONE.
*
******************************************************************************/
static void RTT_StageUpdate(L2_RTT_FSM* rttFsmPtr, L2_RTT_STGE newStage) {
ASSERT(rttFsmPtr != NULL);
ASSERT(newStage >= RTT_NONE_STAGE && newStage <= RTT_RSP2);
DBG_INFO("RTT Stage Update: %d -> %d.\n", rttFsmPtr->rttStage, newStage);
rttFsmPtr->rttStage = newStage;
}
/*****************************************************************************/
/**
* @brief Reset RTT FSM
*
* @param rttFsmPtr a pointer to rtt FSM instance.
*
* @return NONE
*
******************************************************************************/
void RTT_Reset(L2_RTT_FSM* rttFsmPtr){
ASSERT(rttFsmPtr != NULL);
memset(&(rttFsmPtr->rttRecord), 0x00, sizeof(RTT_RECORD));
rttFsmPtr->rttStage = RTT_REQ1;
rttFsmPtr->isR1Valid = false;
rttFsmPtr->isR2Valid = false;
rttFsmPtr->isR3Valid = false;
rttFsmPtr->isR4Valid = false;
rttFsmPtr->timeStamp.int_part = 0;
rttFsmPtr->timeStamp.frac_part = 0;
rttFsmPtr->doppler = 0;
}
/*****************************************************************************/
/**
* @brief Destroy RTT FSM, free allocated memory.
*
* @param rttFsmPtr a pointer to rtt FSM instance.
*
* @return NONE
*
******************************************************************************/
void RTT_Destroy(L2_RTT_FSM* rttFsmPtr){
free(rttFsmPtr);
}
/*****************************************************************************/
/**
* @brief Get the frame start time. If torType == L2_TOR_TX, get the next
* slot start time, if torType == L2_TOR_RX get last frame start
* time.
*
* @param instPtr a pointer to linklayer layer instance
* @param tmStamp a pointer to store frame start time
* @param torType tx/rx mode
*
* @return NONE
*
******************************************************************************/
void RTT_GetFrameStart(L2_INST* instPtr, TIME_WORD *tmStamp, L2_TOR_TYPE torType){
ASSERT(instPtr != NULL);
ASSERT(tmStamp != NULL);
// Get the next frame start time
if(torType == L2_TOR_TX) {
tmStamp->int_part = L2_GetNextFrameNum(instPtr)*L2_SLOTS_PER_FRAME + L2_GetNextSlotNum(instPtr);
tmStamp->frac_part = 0 ;
}
// Get the last reiceive frame start time
else if(torType == L2_TOR_RX) {
PHY_INST* phyRef = instPtr->config.phyInstPtr;
TIME_WORD timeStamp;
int64_t timeDiff;
Phy_GetFrameSyncTimeStamp(phyRef, &timeStamp);
timeDiff = (uint64_t) timeStamp.frac_part;
timeDiff += ((uint64_t)timeStamp.int_part) * COUNTE_FRAC_MAX;
Phy_GetLastSlotStartTimeStamp(phyRef, tmStamp);
timeDiff -= ((uint64_t) tmStamp->int_part) * COUNTE_FRAC_MAX;
timeDiff -= (uint64_t) tmStamp->frac_part;
timeDiff = (int64_t)Phy_GetTimeComp(L2_L2frame2L1frame(L2_GetLastFrameType(instPtr))) - timeDiff;
if (timeDiff < 0) {
timeDiff += COUNTE_FRAC_MAX;
tmStamp->int_part--;
_nop_();
}
tmStamp->frac_part = (TIME_FRAC)timeDiff;
}
else {
*tmStamp = RTT_TIME_NONE;
DBG_ERROR("Unexpected tx/rx mode, setting dummy values.\n");
}
}
/*****************************************************************************/
/**
* @brief Calculate tmA - tmA.
*
* @param tmA time stamp A
* @param tmA time stamp B
* @param tRound t round
*
* @return NONE
*
******************************************************************************/
void RTT_CalculateTimeGap(const TIME_WORD *tmA, const TIME_WORD *tmB, TIME_WORD *tRound){
ASSERT(tmA != NULL);
ASSERT(tmB != NULL);
ASSERT(tRound != NULL);
uint64_t timeDiff;
timeDiff = (uint64_t) tmB->frac_part;
timeDiff += ((uint64_t)tmB->int_part) * COUNTE_FRAC_MAX;
timeDiff -= ((uint64_t)tmA->int_part) * COUNTE_FRAC_MAX;
timeDiff -= (uint64_t) tmA->frac_part;
tRound->frac_part = (TIME_FRAC)(timeDiff % COUNTE_FRAC_MAX);
tRound->frac_part = (TIME_INT)(timeDiff / COUNTE_FRAC_MAX);
}
/*****************************************************************************/
/**
* @brief Initialize RTT FSM, allocate memory for FSM instance.
*
* @param rttFsmPtr
*
* @return SUCCESS Initialization successful.
* EMAC_MEMORY_ALLOC_ERROR Memory allocate error.
*
******************************************************************************/
int32_t RTT_Init(L2_RTT_FSM** rttFsmPtr){
(*rttFsmPtr) = (L2_RTT_FSM*) malloc(sizeof(L2_RTT_FSM));
if (*rttFsmPtr == NULL) {
free(*rttFsmPtr);
return EALLOC;
}
RTT_Reset(*rttFsmPtr);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Update RTT FSM accordingly.
*
* @param instPtr a pointer to linklayer layer instance
* @param torType tx/rx mode type
*
* @return SUCCESS
* error code
*
******************************************************************************/
int32_t RTT_FsmUpdate(L2_INST* instPtr, L2_TOR_TYPE torType) {
ASSERT(instPtr != NULL);
L2_RTT_FSM* rttFsmPtr = L2_GetRttFsm(instPtr);
RTT_RECORD* rttRecord = &(rttFsmPtr->rttRecord);
PHY_INST *phyRef = instPtr->config.phyInstPtr;
DBG_INFO("-------- RTT FSM Update --------\n");
// Stage trans
// For Head Node: Tx->Rx->Tx->Rx
if(L2_GetNodeType(instPtr) == HEAD_NODE){
switch(rttFsmPtr->rttStage) {
case RTT_REQ1 :
if(torType == L2_TOR_TX){
DBG_INFO("Prepare data for RTT REQ-1\n");
// Update Tt1
RTT_GetFrameStart(instPtr, &(rttRecord->Tt1), torType);
DBG_INFO("Tt1-timeL:%u.\n", rttRecord->Tt1.int_part);
DBG_INFO("Tt1-timeH:%u.\n", rttRecord->Tt1.frac_part);
// Prepare data for sending...
rttFsmPtr->timeStamp = rttRecord->Tt1;
rttFsmPtr->doppler = RTT_DOPPLER_NONE;
RTT_StageUpdate(rttFsmPtr, RTT_RSP1);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP1 :
if(torType == L2_TOR_RX){
if(L2_isDataAvail(instPtr) == true){
DBG_INFO("RTT RSP-1 have been received.\n");
DBG_INFO("Preparing data for RTT REQ-2.\n");
rttFsmPtr->isR2Valid = true;
// Update doppler
rttRecord->dopplerR2 = (int32_t)Phy_GetCoarseFreqEst(phyRef);
// Update Tr2
RTT_GetFrameStart(instPtr, &(rttRecord->Tr2), torType);
// Calculate TroundA
RTT_CalculateTimeGap(&(rttRecord->Tt1), &(rttRecord->Tr2), &(rttRecord->TroundA));
}
else{
DBG_WARNING("RTT RSP-1 had not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set Tr2 dopplerR2 and TroundA to dummy value.\n");
rttFsmPtr->isR2Valid = false;
rttRecord->dopplerR2 = RTT_DOPPLER_NONE;
rttRecord->Tr2 = RTT_TIME_NONE;
rttRecord->TroundA = RTT_TIME_NONE;
}
DBG_INFO("dopplerR2:%d.\n", rttRecord->dopplerR2);
DBG_INFO("Tr2-timeL:%u.\n", rttRecord->Tr2.frac_part);
DBG_INFO("Tr2-timeH:%u.\n", rttRecord->Tr2.int_part);
DBG_INFO("TroundA-timeL:%u.\n", rttRecord->TroundA.frac_part);
DBG_INFO("TroundA-timeH:%u.\n", rttRecord->TroundA.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_REQ2);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_REQ2 :
if(torType == L2_TOR_TX){
DBG_INFO("Prepare data for RTT REQ-2\n");
// Update Tt3
RTT_GetFrameStart(instPtr, &(rttRecord->Tt3), torType);
if ( rttFsmPtr->isR2Valid ) {
// Calculate reply A
RTT_CalculateTimeGap(&(rttRecord->Tt3), &(rttRecord->Tr2), &(rttRecord->TreplyA));
}
else {
DBG_WARNING("RTT RSP-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set TreplyA to dummy value.\n");
rttRecord->TreplyA = RTT_TIME_NONE;
}
DBG_INFO("Tt3-timeL:%u.\n", rttRecord->Tt3.frac_part);
DBG_INFO("Tt3-timeH:%u.\n", rttRecord->Tt3.int_part);
DBG_INFO("TreplyA-timeL:%u.\n", rttRecord->TreplyA.frac_part);
DBG_INFO("TreplyA-timeH:%u.\n", rttRecord->TreplyA.int_part);
// Prepare data for sending.
rttFsmPtr->timeStamp = rttRecord->TroundA;
rttFsmPtr->doppler = rttRecord->dopplerR2;
RTT_StageUpdate(rttFsmPtr, RTT_RSP2);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP2 :
if(torType == L2_TOR_RX){
if(L2_isDataAvail(instPtr) == true){
DBG_INFO("RTT RSP-2 have been received.\n");
rttFsmPtr->isR4Valid = true;
// Update doppler
double doppler = Phy_GetCoarseFreqEst(phyRef);
rttRecord->dopplerR2 = (int32_t)doppler;
// Update Tr4
RTT_GetFrameStart(instPtr, &(rttRecord->Tr4), torType);
// Calculate TroundA
RTT_CalculateTimeGap(&(rttRecord->Tt3), &(rttRecord->Tr4), &(rttRecord->TroundA));
}
else{
DBG_WARNING("RTT RSP-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set Tr4 dopplerR4 and TroundA to dummy value.\n");
rttFsmPtr->isR4Valid = false;
rttRecord->dopplerR4 = RTT_DOPPLER_NONE;
rttRecord->Tr4 = RTT_TIME_NONE;
rttRecord->TroundA = RTT_TIME_NONE;
}
DBG_INFO("dopplerR4:%d.\n", rttRecord->dopplerR4);
DBG_INFO("Tr4-timeL:%u.\n", rttRecord->Tr4.frac_part);
DBG_INFO("Tr4-timeH:%u.\n", rttRecord->Tr4.int_part);
DBG_INFO("TroundA-timeL:%u.\n", rttRecord->TroundA.frac_part);
DBG_INFO("TroundA-timeH:%u.\n", rttRecord->TroundA.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_REQ1);
DBG_INFO("RTT procedure end...\n");
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
default :
DBG_ERROR("Unexpected RTT FSM stage [%d].\n", rttFsmPtr->rttStage);
break;
}
}
// For Member Node: Rx->Tx->Rx->Tx
else{
switch(rttFsmPtr->rttStage) {
case RTT_REQ1 :
if(torType == L2_TOR_RX){
if(L2_isDataAvail(instPtr) == true){
DBG_INFO("RTT REQ-1 have been received.\n");
DBG_INFO("Preparing data for RTT RSP-1.\n");
rttFsmPtr->isR2Valid = true;
// Update doppler
rttRecord->dopplerR2 = (int32_t)Phy_GetCoarseFreqEst(phyRef);
// Update Tr1
RTT_GetFrameStart(instPtr, &(rttRecord->Tr1), torType);
}
else{
DBG_WARNING("RTT REQ-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set dopplerR1 and Tr1 to dummy value.\n");
rttFsmPtr->isR1Valid = false;
rttRecord->dopplerR1 = RTT_DOPPLER_NONE;
rttRecord->Tr1 = RTT_TIME_NONE;
}
DBG_INFO("dopplerR1:%d.\n", rttRecord->dopplerR1);
DBG_INFO("Tr1-timeL:%u.\n", rttRecord->Tr1.frac_part);
DBG_INFO("Tr1-timeH:%u.\n", rttRecord->Tr1.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_RSP1);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP1 :
if(torType == L2_TOR_TX){
DBG_INFO("Prepare data for RTT RSP-1\n");
// Update Tt2
RTT_GetFrameStart(instPtr, &(rttRecord->Tt2), torType);
if ( rttFsmPtr->isR1Valid ) {
// Calculate reply B
RTT_CalculateTimeGap(&(rttRecord->Tr1), &(rttRecord->Tt2), &(rttRecord->TreplyB));
}
else {
rttRecord->TreplyB = RTT_TIME_NONE;
DBG_WARNING("RTT REQ-1 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set ReplayB to dummy value.\n");
}
DBG_INFO("Tt2-timeL:%u.\n", rttRecord->Tt2.frac_part);
DBG_INFO("Tt2-timeH:%u.\n", rttRecord->Tt2.int_part);
DBG_INFO("TreplyB-timeL:%u.\n", rttRecord->TreplyB.frac_part);
DBG_INFO("TreplyB-timeH:%u.\n", rttRecord->TreplyB.int_part);
// Prepare data for sending.
rttFsmPtr->timeStamp = rttRecord->TreplyB;
rttFsmPtr->doppler = rttRecord->dopplerR1;
RTT_StageUpdate(rttFsmPtr, RTT_REQ2);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_REQ2 :
if(torType == L2_TOR_RX){
if(L2_isDataAvail(instPtr) == true){
DBG_INFO("RTT REQ-2 have been received.\n");
DBG_INFO("Preparing data for RTT RSP-2.\n");
rttFsmPtr->isR3Valid = true;
// Update doppler
rttRecord->dopplerR2 = (int32_t)Phy_GetCoarseFreqEst(phyRef);
// Update Tr3
RTT_GetFrameStart(instPtr, &(rttRecord->Tr3), torType);
// Calculate TroundB
RTT_CalculateTimeGap(&(rttRecord->Tt2), &(rttRecord->Tr3), &(rttRecord->TroundB));
}
else{
DBG_WARNING("RTT REQ-2 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set dopplerR3 and ReplayB to dummy value.\n");
rttFsmPtr->isR3Valid = false;
rttRecord->dopplerR3 = RTT_DOPPLER_NONE;
rttRecord->TroundB = RTT_TIME_NONE;
}
DBG_INFO("dopplerR3:%d.\n", rttRecord->dopplerR3);
DBG_INFO("Tr3-timeL:%u.\n", rttRecord->Tr3.frac_part);
DBG_INFO("Tr3-timeH:%u.\n", rttRecord->Tr3.int_part);
DBG_INFO("TroundB-timeL:%u.\n", rttRecord->TroundB.frac_part);
DBG_INFO("TroundB-timeH:%u.\n", rttRecord->TroundB.int_part);
RTT_StageUpdate(rttFsmPtr, RTT_RSP2);
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
case RTT_RSP2 :
if(torType == L2_TOR_TX){
DBG_INFO("Prepare data for RTT RSP-2\n");
// Update Tt4
RTT_GetFrameStart(instPtr, &(rttRecord->Tt4), torType);
if ( rttFsmPtr->isR3Valid ) {
// Calculate reply B
RTT_CalculateTimeGap(&(rttRecord->Tr3), &(rttRecord->Tt4), &(rttRecord->TreplyB));
// TODO: implement a time adjustment.
}
else {
DBG_WARNING("RTT REQ-2 have not been received [Stage: %d].\n", rttFsmPtr->rttStage);
DBG_WARNING("Set ReplayB to dummy value.\n");
rttRecord->TreplyB = RTT_TIME_NONE;
}
DBG_INFO("Tt4-timeL:%u.\n", rttRecord->Tt4.frac_part);
DBG_INFO("Tt4-timeH:%u.\n", rttRecord->Tt4.int_part);
DBG_INFO("TreplyB-timeL:%u.\n", rttRecord->TreplyB.frac_part);
DBG_INFO("TreplyB-timeH:%u.\n", rttRecord->TreplyB.int_part);
// Prepare data for sending.
rttFsmPtr->timeStamp = rttRecord->TreplyB;
rttFsmPtr->doppler = rttRecord->dopplerR3;
RTT_StageUpdate(rttFsmPtr, RTT_REQ1);
DBG_INFO("RTT procedure end...\n");
}
else{
DBG_INFO("RTT FSM remain current state [%d].\n", rttFsmPtr->rttStage);
}
break;
default:
DBG_ERROR("Unexpected RTT FSM stage [%d].\n", rttFsmPtr->rttStage);
break;
}
}
return SUCCESS;
}
}
+182 -143
View File
@@ -20,10 +20,10 @@
/***************************** Include Files *********************************/
#include <stdint.h>
#include "config/app_config.h"
#include "xscugic.h" // The generic interrupt controller driver component
#include "xil_exception.h" // ARM Cortex A9 specific exception related APIs
#include "xscugic.h" // The generic interrupt controller driver component
#include "xil_exception.h" // ARM Cortex A9 specific exception related APIs
#include "xgpio.h"
#include "sleep.h" // Sleep APIs for Cortex A9
#include "sleep.h" // Sleep APIs for Cortex A9
#include "xil_cache.h"
#include "linklayer/linklayer814.h"
#include "linklayer/msg_def.h"
@@ -39,7 +39,7 @@
/************************** Constant Definitions *****************************/
L2_CONFIG l2Config = {
.myType = MEMBER_NODE,
.myType = L2_NODE_MEMBER,
.isInterHead = false,
.myId = 2,
.clustId = 1,
@@ -47,38 +47,36 @@ L2_CONFIG l2Config = {
.bkpHeadId = 1,
.netScale = 2,
.phyInstPtr = NULL,
.tmcInstPtr = NULL
};
.tmcInstPtr = NULL};
TIMECTRL_CONFIG tmcConfig = {
TMC_CONFIG tmcConfig = {
.baseAddr = TIME_CONTROLLER_BASEADDR,
.reset = 10
};
.reset = 10};
PHY_CONFIG l1Config = {
.devId = PHY_DEVICE_ID,
.txBramId = TXBUFF_BRAM_ID,
.rxBramId = RXBUFF_BRAM_ID,
.antBramId = ANTCONFIG_BRAM_ID,
.baseAddr = PHY_CTRL_BASEADDR
};
.baseAddr = PHY_CTRL_BASEADDR};
MPC_CONFIG mpcConfig = {
.bramDevId = MPC_PCIE_BRAM_ID,
.msgLenMax = MPC_BUFFER_LENGTH //byte
.msgLenMax = MPC_BUFFER_LENGTH // byte
};
static bool mpcStatusUpAssert = false;
/************************** Function Prototypes ******************************/
int SetupInterruptSystem(XScuGic* instPtr, uint32_t devId);
int SetupInterruptSystem(XScuGic *instPtr, uint32_t devId);
void PhysicalIntr_Handler(void *callBackRef);
void PeriodicPull_Handler(void *callBackRef);
#ifdef _MPC_CTRL
void MPC_IntrHandler(void* CallBackRef);
void MPC_IntrHandler(void *callBackRef);
#endif
/*********************** Driver Instance Definitions **************************/
TIMECTRL_INST* tmcInstPtr = NULL;
PHY_INST* phyInstPtr = NULL;
L2_INST* linkInstPtr = NULL;
static XScuGic gicInst; //General interrupt controller intance
TMC_INST *tmcInstPtr = NULL;
PHY_INST *phyInstPtr = NULL;
L2_INST *linkInstPtr = NULL;
static XScuGic gicInst; // General interrupt controller intance
// FIXME: Only for test...
XGpio configGpio; /* The Instance of the GPIO Driver */
/****************************************************************************/
@@ -95,21 +93,24 @@ XGpio configGpio; /* The Instance of the GPIO Driver */
* FAILURE if initialization failed.
*
*****************************************************************************/
int SetupInterruptSystem(XScuGic* instPtr, uint32_t devId){
int SetupInterruptSystem(XScuGic *instPtr, uint32_t devId)
{
XScuGic_Config *configPtr;
int Status;
uint32_t intrState;
// Initialize the GIC instance.
configPtr = XScuGic_LookupConfig(devId);
Status = XScuGic_CfgInitialize(instPtr, configPtr,
configPtr->CpuBaseAddress);
if (Status != SUCCESS) {
configPtr->CpuBaseAddress);
if (Status != SUCCESS)
{
return Status;
}
// Perform a self-test to ensure that the hardware was built correctly.
Status = XScuGic_SelfTest(instPtr);
if (Status != SUCCESS) {
if (Status != SUCCESS)
{
return Status;
}
// Clear any pending interrupt flags
@@ -134,37 +135,52 @@ int SetupInterruptSystem(XScuGic* instPtr, uint32_t devId){
* rising edge 0x03.
*/
// Initialize physical layer interrupt.
XScuGic_SetPriorityTriggerType(instPtr, PHY_INTR_ID, 0x00, 0x03);
// Connect the interrupt service routine isr1 to the interrupt controller
Status = XScuGic_Connect(instPtr, PHY_INTR_ID,
(Xil_ExceptionHandler)PhysicalIntr_Handler, (void *)phyInstPtr);
if (Status != SUCCESS)
{
return Status;
}
// Initialize physical layer interrupt.
XScuGic_SetPriorityTriggerType(instPtr, PERIODIC_5MS_INTR_ID, 0x00, 0x03);
// Connect the interrupt service routine isr1 to the interrupt controller
Status = XScuGic_Connect(instPtr, PERIODIC_5MS_INTR_ID,
(Xil_ExceptionHandler) PeriodicPull_Handler, (void *) instPtr);
if (Status != SUCCESS) {
(Xil_ExceptionHandler)PeriodicPull_Handler, (void *)linkInstPtr);
if (Status != SUCCESS)
{
return Status;
}
XScuGic_Enable(instPtr, PERIODIC_5MS_INTR_ID);
#ifdef _MPC_CTRL
// Initialize MPC interrupt.
XScuGic_SetPriorityTriggerType(instPtr, MPC_RX_DONE_INTR_ID, 0x00, 0x03);
// Connect the interrupt service routine isr1 to the interrupt controller
Status = XScuGic_Connect(instPtr, MPC_RX_DONE_INTR_ID,
(Xil_ExceptionHandler) MPC_IntrHandler, (void *) instPtr);
if (Status != XST_SUCCESS) {
(Xil_ExceptionHandler)MPC_IntrHandler, (void *)mpcInstPtr);
if (Status != XST_SUCCESS)
{
return Status;
}
XScuGic_Enable(instPtr, MPC_RX_DONE_INTR_ID);
#endif
XScuGic_Enable(instPtr, PHY_INTR_ID);
XScuGic_Enable(instPtr, PERIODIC_5MS_INTR_ID);
/* Initialize the exception table and register the interrupt controller
* handler with the exception table
*/
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler,
(void *) instPtr);
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
(void *)instPtr);
// Enable non-critical exceptions
Xil_ExceptionEnable();
@@ -172,10 +188,9 @@ int SetupInterruptSystem(XScuGic* instPtr, uint32_t devId){
return Status;
} // SetupInterruptSystem
#ifdef _MPC_CTRL
void MPC_PCIESentStart(){
void MPC_PCIESentStart()
{
uint32_t GpioConfig = XGpio_DiscreteRead(&configGpio, 2);
GpioConfig ^= 0x00000002;
XGpio_DiscreteWrite(&configGpio, 2, GpioConfig);
@@ -185,104 +200,116 @@ void MPC_PCIESentStart(){
/**
* @brief Handler of mater pc contrl interrupt.
*
* @param CallBackRef A pointer to corresponding frame UART instance.
* @param callBackRef A pointer to corresponding mpcInstPtr instance.
*
* @return None.
*
******************************************************************************/
void MPC_IntrHandler(void* CallBackRef) {
void MPC_IntrHandler(void *callBackRef)
{
MPC_MsgHandler(mpcInstPtr);
}
#endif
/*****************************************************************************/
/**
* @brief Handler of physical layer interrupt.
*
* @param callBackRef A pointer to corresponding physical layer instance.
*
* @return None.
*
******************************************************************************/
void PhysicalIntr_Handler(void *callBackRef)
{
Phy_UpdateState(phyInstPtr);
if (phyInstPtr->tor.curr == PHY_TOR_TX)
{
switch (phyInstPtr->frameType.curr)
{
case L1_1M2BPS_5MS_FRAME:
mpcRecord->frame1Sent++;
break;
case L1_200KBPS_5MS_FRAME:
mpcRecord->frame2Sent++;
break;
case L1_40KBPS_10MS_FRAME:
mpcRecord->frame3Sent++;
break;
case L1_40KBPS_20MS_FRAME:
mpcRecord->frame4Sent++;
break;
case L1_10KBPS_20MS_FRAME:
mpcRecord->frame5Sent++;
break;
case L1_2KBPS_100MS_FRAME:
mpcRecord->frame6Sent++;
break;
case L1_10KBPS_10MS_FRAME:
mpcRecord->frame7Sent++;
break;
case L1_2KBPS_20MS_FRAME:
mpcRecord->frame8Sent++;
break;
default:
break;
}
}
if (phyInstPtr->tor.last == PHY_TOR_RX && phyInstPtr->isFrameSync)
{
switch (phyInstPtr->frameType.last)
{
case L1_1M2BPS_5MS_FRAME:
mpcRecord->frame1Recv++;
break;
case L1_200KBPS_5MS_FRAME:
mpcRecord->frame2Recv++;
break;
case L1_40KBPS_10MS_FRAME:
mpcRecord->frame3Recv++;
break;
case L1_40KBPS_20MS_FRAME:
mpcRecord->frame4Recv++;
break;
case L1_10KBPS_20MS_FRAME:
mpcRecord->frame5Recv++;
break;
case L1_2KBPS_100MS_FRAME:
mpcRecord->frame6Recv++;
break;
case L1_10KBPS_10MS_FRAME:
mpcRecord->frame7Recv++;
break;
case L1_2KBPS_20MS_FRAME:
mpcRecord->frame8Recv++;
break;
default:
break;
}
}
}
/****************************************************************************/
/**
* This function is a interrupt service routine for IRQ_F2P[1:1], IRQ_F2P[1:1]
* tells CPU that the data in OCM is ready!
* Handler of periodic 5ms interrupt
*
* @param callBackRef is the SCUGIC instance pointer.
* @param callBackRef is the linklayer instance pointer.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
void PeriodicPull_Handler(void *callBackRef) {
void PeriodicPull_Handler(void *callBackRef)
{
int32_t Status;
Phy_UpdateState(phyInstPtr);
uint32_t GpioConfig = XGpio_DiscreteRead(&configGpio, 2);
if(phyInstPtr->TOR.curr == PHY_TOR_TX){
switch(phyInstPtr->frameType.curr){
case L1_1M2BPS_5MS_FRAME:
mpcRecord->frame1Sent ++ ;
break;
case L1_200KBPS_5MS_FRAME:
mpcRecord->frame2Sent ++ ;
break;
case L1_40KBPS_10MS_FRAME:
mpcRecord->frame3Sent ++ ;
break;
case L1_40KBPS_20MS_FRAME:
mpcRecord->frame4Sent ++ ;
break;
case L1_10KBPS_20MS_FRAME:
mpcRecord->frame5Sent ++ ;
break;
case L1_2KBPS_100MS_FRAME:
mpcRecord->frame6Sent ++ ;
break;
case L1_10KBPS_10MS_FRAME:
mpcRecord->frame7Sent ++ ;
break;
case L1_2KBPS_20MS_FRAME:
mpcRecord->frame8Sent ++ ;
break;
default:
break;
}
}
if(phyInstPtr->TOR.last == PHY_TOR_RX && phyInstPtr->isFrameSync){
switch(phyInstPtr->frameType.last){
case L1_1M2BPS_5MS_FRAME:
mpcRecord->frame1Recv ++ ;
break;
case L1_200KBPS_5MS_FRAME:
mpcRecord->frame2Recv ++ ;
break;
case L1_40KBPS_10MS_FRAME:
mpcRecord->frame3Recv ++ ;
break;
case L1_40KBPS_20MS_FRAME:
mpcRecord->frame4Recv ++ ;
break;
case L1_10KBPS_20MS_FRAME:
mpcRecord->frame5Recv ++ ;
break;
case L1_2KBPS_100MS_FRAME:
mpcRecord->frame6Recv ++ ;
break;
case L1_10KBPS_10MS_FRAME:
mpcRecord->frame7Recv ++ ;
break;
case L1_2KBPS_20MS_FRAME:
mpcRecord->frame8Recv ++ ;
break;
default:
break;
}
}
Status = Linklayer_Proc(linkInstPtr);
if(Status != SUCCESS){
if (Status != SUCCESS)
{
DBG_ERROR("Link layer runs failed, with error code: %ld\n", Status);
_nop_();
}
if(L2_isDataAvail(linkInstPtr) == true ){
GpioConfig^=0x00000001;
}
if (linkInstPtr->slotNum.next % DATA_STORE_INTERVAL == 1) {
if (linkInstPtr->slotNum.next % DATA_STORE_INTERVAL == 1)
{
mpcStatusUpAssert = true;
mpcRecord->frame1Cnt = mpcRecord->frame1Recv - mpcRecord->frame1CntLast;
mpcRecord->frame2Cnt = mpcRecord->frame2Recv - mpcRecord->frame2CntLast;
@@ -304,11 +331,13 @@ void PeriodicPull_Handler(void *callBackRef) {
mpcRecord->frame8CntLast = mpcRecord->frame8Recv;
}
// TODO: Dijian frequency pattern TX_RX State.
GpioConfig ^= 0x80000000;
GpioConfig = (phyInstPtr->TOR.next == PHY_TOR_TX) ? GpioConfig|0x40000000 : GpioConfig&0xBFFFFFFF;
uint32_t GpioConfig = XGpio_DiscreteRead(&configGpio, 2);
if (L2_isDataAvail(linkInstPtr) == true)
{
GpioConfig ^= 0x00000001;
}
XGpio_DiscreteWrite(&configGpio, 2, GpioConfig);
} // PhyIntr_Handler
} // PeriodicPull_Handler
/*****************************************************************************/
/**
@@ -320,19 +349,23 @@ void PeriodicPull_Handler(void *callBackRef) {
* @return
*
******************************************************************************/
int main(void) {
int main(void)
{
int Status;
Status = HARDWARE_initialize();
if (Status == SUCCESS) {
if (Status == SUCCESS)
{
DBG_PRINT("Hardware Init SUCCESS! \n");
}
else {
else
{
DBG_PRINT("Hardware Init FAILED! \n");
return Status;
}
Status = XGpio_Initialize(&configGpio, XPAR_CONFIG_GPIO_DEVICE_ID);
if (Status != SUCCESS) {
if (Status != SUCCESS)
{
DBG_PRINT("Config Gpio Initialization Failed\n");
return FAILURE;
}
@@ -341,20 +374,24 @@ int main(void) {
// Init time controller
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
if (Status == SUCCESS) {
if (Status == SUCCESS)
{
DBG_PRINT("TmcCtrl Init SUCCESS! \n");
}
else {
else
{
DBG_PRINT("TmcCtrl Init FAILED! \n");
return Status;
}
// Init physical layer
Status = Phy_InstInit(&phyInstPtr, &l1Config);
if (Status == SUCCESS) {
if (Status == SUCCESS)
{
DBG_PRINT("PhyCtrl Init SUCCESS! \n");
}
else {
else
{
DBG_PRINT("PhyCtrl Init FAILED! \n");
return Status;
}
@@ -364,58 +401,60 @@ int main(void) {
l2Config.tmcInstPtr = tmcInstPtr;
Status = Linklayer_Init(&linkInstPtr, &l2Config);
if (Status == SUCCESS) {
if (Status == SUCCESS)
{
DBG_PRINT("LinkLayer Init SUCCESS! \n");
}
else {
else
{
DBG_PRINT("Linklayer Init FAILED! \n");
return Status;
}
// Init MPC
Status = MPC_Init(&mpcInstPtr, &mpcConfig);
if (Status == SUCCESS) {
if (Status == SUCCESS)
{
DBG_PRINT("MPC Init SUCCESS! \n");
}
else {
else
{
DBG_PRINT("MPC Init FAILED! \n");
return Status;
}
// Initialize GIC.
Status = SetupInterruptSystem(&gicInst ,SCUGIC_DEVICE_ID);
if (Status == SUCCESS) {
Status = SetupInterruptSystem(&gicInst, SCUGIC_DEVICE_ID);
if (Status == SUCCESS)
{
DBG_PRINT("Intc Init SUCCESS! \n");
}
else {
else
{
DBG_PRINT("Intc Init FAILED! \n");
return Status;
}
Status = Phy_SetMode(phyInstPtr, PHY_MODE_SCHEDULE);
if (Status == SUCCESS) {
DBG_PRINT("Physical Mode %u Setup SUCCESS! \n", PHY_MODE_LISTEN);
}
else {
DBG_PRINT("Physical Mode %u Setup FAILED! \n", PHY_MODE_LISTEN);
return Status;
}
DBG_PRINT("Starting Physical Layer...");
Phy_Start(phyInstPtr);
// FIXME: only for debug, linklayer should be start by MPC
Linklayer_Start(linkInstPtr);
while(true) {
if (mpcStatusUpAssert == true) {
while (true)
{
if (mpcStatusUpAssert == true)
{
mpcStatusUpAssert = false;
if (linkInstPtr->buffSwitch == 0) {
if (linkInstPtr->buffSwitch == 0)
{
MPC_StateUpload(mpcInstPtr, linkInstPtr->mgmtMsgRecvBuff1, linkInstPtr->mgmtMsgRecvCnt1,
linkInstPtr->svcMsgRecvBuff1, linkInstPtr->svcMsgRecvCnt1, &(linkInstPtr->mgmtNetFSM->mgmtMsgLog));
linkInstPtr->svcMsgRecvBuff1, linkInstPtr->svcMsgRecvCnt1, &(linkInstPtr->mgmtFSM->mgmtMsgLog));
}
else {
else
{
MPC_StateUpload(mpcInstPtr, linkInstPtr->mgmtMsgRecvBuff0, linkInstPtr->mgmtMsgRecvCnt0,
linkInstPtr->svcMsgRecvBuff0, linkInstPtr->svcMsgRecvCnt0, &(linkInstPtr->mgmtNetFSM->mgmtMsgLog));
linkInstPtr->svcMsgRecvBuff0, linkInstPtr->svcMsgRecvCnt0, &(linkInstPtr->mgmtFSM->mgmtMsgLog));
}
}
}
+155 -125
View File
@@ -1,18 +1,18 @@
/*****************************************************************************/
/**
* Description: A brief description of this file
*
*
* Date: 2022-01-19 00:54
* LastEditors: Fan Hao
* LastEditTime: 2022-03-28 20:24
* Revisions: Rev 0.0
* History:
* History:
* [2022-01-19]: Initial version.
* [2022-03-28]: Add general information print function.
*
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
#include <inttypes.h>
@@ -31,8 +31,8 @@
#define STATE_STROAGE_BUFF_MAX 32768 // 32K Bytes
static int32_t MPC_InsertChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint64_t chunk);
static int32_t MPC_GetChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint64_t* chunk);
static int32_t MPC_InsertChunk(BIT_ARRAY *bitarr, uint32_t offset, uint32_t numBit, uint64_t chunk);
static int32_t MPC_GetChunk(BIT_ARRAY *bitarr, uint32_t offset, uint32_t numBit, uint64_t *chunk);
#ifdef _MPC_UART
#include <frame_uart.h>
@@ -44,19 +44,18 @@ static int32_t MPC_GetChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit,
#include "../phy_ctrl/phy_ctrl.h"
extern L2_CONFIG l2Config;
extern PHY_INST* phyInstPtr;
extern L2_INST* linkInstPtr;
extern PHY_INST *phyInstPtr;
extern L2_INST *linkInstPtr;
MPC_INST* mpcInstPtr = NULL;
MPC_RECORD* mpcRecord = NULL;
BIT_ARRAY* mpcTxMsgBuff = NULL;
BIT_ARRAY* mpcRxMsgBuff = NULL;
MPC_INST *mpcInstPtr = NULL;
MPC_RECORD *mpcRecord = NULL;
BIT_ARRAY *mpcTxMsgBuff = NULL;
BIT_ARRAY *mpcRxMsgBuff = NULL;
static MPC_MSG_HEADER mpcHeader = {
.head = 0x5302,
};
/*****************************************************************************/
/**
* @brief Insert a data chunk to a bit array.
@@ -71,9 +70,11 @@ static MPC_MSG_HEADER mpcHeader = {
* SUCCESS
*
******************************************************************************/
static int32_t MPC_InsertChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint64_t chunk){
static int32_t MPC_InsertChunk(BIT_ARRAY *bitarr, uint32_t offset, uint32_t numBit, uint64_t chunk)
{
ASSERT(bitarr != NULL);
if(bitarr->num_of_bits < offset+numBit){
if (bitarr->num_of_bits < offset + numBit)
{
return FAILURE;
}
bit_array_set_wordn(bitarr, offset, chunk, numBit);
@@ -94,21 +95,25 @@ static int32_t MPC_InsertChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numB
* SUCCESS
*
******************************************************************************/
static int32_t MPC_GetChunk(BIT_ARRAY* bitarr, uint32_t offset, uint32_t numBit, uint64_t* chunk){
static int32_t MPC_GetChunk(BIT_ARRAY *bitarr, uint32_t offset, uint32_t numBit, uint64_t *chunk)
{
ASSERT(bitarr != NULL);
if(bitarr->num_of_bits < offset+numBit || numBit > 64){
if (bitarr->num_of_bits < offset + numBit || numBit > 64)
{
return FAILURE;
}
*chunk = bit_array_get_wordn(bitarr, offset, numBit);
return SUCCESS;
}
static uint32_t MPC_GetMsgLen(MPC_MSG_TYPE type){
switch(type){
static uint32_t MPC_GetMsgLen(MPC_MSG_TYPE type)
{
switch (type)
{
case MPC_MSG_TEST:
return (MPC_MSG_TEST_LEN/8);
return (MPC_MSG_TEST_LEN / 8);
case MPC_MSG_STATE:
return (MPC_MSG_STATE_LEN/8);
return (MPC_MSG_STATE_LEN / 8);
default:
return MPC_MSG_LEN_NONE;
}
@@ -124,13 +129,15 @@ static uint32_t MPC_GetMsgLen(MPC_MSG_TYPE type){
* error code.
*
******************************************************************************/
int MPC_Init(MPC_INST** instPtr, MPC_CONFIG* configPtr){
int MPC_Init(MPC_INST **instPtr, MPC_CONFIG *configPtr)
{
ASSERT(instPtr != NULL);
ASSERT(configPtr != NULL);
int Status = SUCCESS;
XBram_Config *bramConfigPtr;
(*instPtr) = (MPC_INST*)malloc(sizeof(MPC_INST));
if((*instPtr) == NULL){
(*instPtr) = (MPC_INST *)malloc(sizeof(MPC_INST));
if ((*instPtr) == NULL)
{
Status = EALLOC;
goto init_failed;
}
@@ -138,41 +145,49 @@ int MPC_Init(MPC_INST** instPtr, MPC_CONFIG* configPtr){
(*instPtr)->configs.msgLenMax = configPtr->msgLenMax;
bramConfigPtr = XBram_LookupConfig(configPtr->bramDevId);
if (bramConfigPtr == NULL) {
if (bramConfigPtr == NULL)
{
Status = EDINVAL;
goto init_failed;
}
Status = XBram_CfgInitialize(&((*instPtr)->pcieBram), bramConfigPtr,
bramConfigPtr->CtrlBaseAddress);
if (Status != SUCCESS) {
bramConfigPtr->CtrlBaseAddress);
if (Status != SUCCESS)
{
goto init_failed;
}
/* Execute the BRAM driver selftest. */
Status = XBram_SelfTest(&((*instPtr)->pcieBram), 0);
if (Status != SUCCESS) {
if (Status != SUCCESS)
{
goto init_failed;
}
(*instPtr)->txBaseAddr = (uint8_t*)((*instPtr)->pcieBram.Config.MemBaseAddress);
(*instPtr)->rxBaseAddr = (uint8_t*)((*instPtr)->pcieBram.Config.MemBaseAddress);
(*instPtr)->txBaseAddr = (uint8_t *)((*instPtr)->pcieBram.Config.MemBaseAddress);
(*instPtr)->rxBaseAddr = (uint8_t *)((*instPtr)->pcieBram.Config.MemBaseAddress);
mpcRecord = (MPC_RECORD*) malloc(sizeof(MPC_RECORD));
if(mpcRecord == NULL){
mpcRecord = (MPC_RECORD *)malloc(sizeof(MPC_RECORD));
if (mpcRecord == NULL)
{
Status = EALLOC;
goto init_failed;
}
memset(mpcRecord, 0x00, sizeof(MPC_RECORD));
mpcTxMsgBuff = bit_array_create(STATE_STROAGE_BUFF_MAX*8);
if(mpcTxMsgBuff == NULL){
mpcTxMsgBuff = bit_array_create(STATE_STROAGE_BUFF_MAX * 8);
if (mpcTxMsgBuff == NULL)
{
goto init_failed;
}
mpcRxMsgBuff = bit_array_create(MPC_MSG_LEN_MAX);
if(mpcRxMsgBuff == NULL){
if (mpcRxMsgBuff == NULL)
{
goto init_failed;
}
return Status;
memset(mpcRecord, 0x00, sizeof(MPC_RECORD));
memset(mpcTxMsgBuff, 0x00, sizeof(STATE_STROAGE_BUFF_MAX * 8));
memset(mpcRxMsgBuff, 0x00, sizeof(MPC_MSG_LEN_MAX));
init_failed:
free(*instPtr);
free(mpcRecord);
@@ -191,69 +206,75 @@ init_failed:
* error code.
*
******************************************************************************/
int MPC_MsgHandler(MPC_INST* instPtr){
int MPC_MsgHandler(MPC_INST *instPtr)
{
ASSERT(instPtr != NULL);
MPC_MSG_HEADER* pktHeader = (MPC_MSG_HEADER*)(instPtr->rxBaseAddr);
MPC_MSG_HEADER *pktHeader = (MPC_MSG_HEADER *)(instPtr->rxBaseAddr);
// instPtr->txBaseAddr + MPC_MSG_HEAD_LEN;
uint64_t dataChunk = 0;
switch(pktHeader->type){
case MPC_MSG_TEST_CODE:
memcpy(mpcRxMsgBuff->words,
instPtr->rxBaseAddr + (MPC_MSG_HEAD_LEN/8),
DIV_ROUND_UP(MPC_MSG_TEST_LEN,8));
MPC_GetChunk(mpcRxMsgBuff, TEST_REQ_CMD_OFFSET, TEST_REQ_CMD_LEN, &dataChunk);
if((uint8_t)dataChunk == TEST_REQ_CMD_START){
MPC_GetChunk(mpcRxMsgBuff, TEST_MODE_SET_OFFSET, TEST_MODE_SET_LEN, &dataChunk);
// FIXME
if((uint8_t)dataChunk == TEST_MODE_HEAD){
l2Config.myType = HEAD_NODE;
l2Config.myId = 1;
}
else{
l2Config.myType = MEMBER_NODE;
l2Config.myId = 2;
}
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_FPGA_ST_OFFSET, TEST_REQ_FPGA_ST_LEN, 0x01);
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_AD_ST_OFFSET, TEST_REQ_AD_ST_LEN, 0x01);
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_RF_ST_OFFSET, TEST_REQ_RF_ST_LEN, 0x01);
MPC_SendMsg(instPtr, MPC_MSG_TEST, (uint8_t*)mpcTxMsgBuff->words, MPC_MSG_TEST_LEN);
Linklayer_Reconfig(linkInstPtr, &l2Config);
Linklayer_Start(linkInstPtr);
switch (pktHeader->type)
{
case MPC_MSG_TEST_CODE:
memcpy(mpcRxMsgBuff->words,
instPtr->rxBaseAddr + (MPC_MSG_HEAD_LEN / 8),
DIV_ROUND_UP(MPC_MSG_TEST_LEN, 8));
MPC_GetChunk(mpcRxMsgBuff, TEST_REQ_CMD_OFFSET, TEST_REQ_CMD_LEN, &dataChunk);
if ((uint8_t)dataChunk == TEST_REQ_CMD_START)
{
MPC_GetChunk(mpcRxMsgBuff, TEST_MODE_SET_OFFSET, TEST_MODE_SET_LEN, &dataChunk);
// TODO: check.
if ((uint8_t)dataChunk == TEST_MODE_HEAD)
{
l2Config.myType = L2_NODE_HEAD;
l2Config.myId = 1;
}
else if((uint8_t)dataChunk == TEST_REQ_CMD_END){
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_FPGA_ST_OFFSET, TEST_REQ_FPGA_ST_LEN, 0x00);
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_AD_ST_OFFSET, TEST_REQ_AD_ST_LEN, 0x00);
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_RF_ST_OFFSET, TEST_REQ_RF_ST_LEN, 0x00);
MPC_SendMsg(instPtr, MPC_MSG_TEST, (uint8_t*)mpcTxMsgBuff->words, MPC_MSG_TEST_LEN);
memset(mpcRecord, 0x00, sizeof(MPC_RECORD));
memset((uint8_t*)mpcTxMsgBuff->words,0x00,STATE_STROAGE_BUFF_MAX);
Linklayer_Halt(linkInstPtr);
MPC_SendMsg(instPtr, MPC_MSG_STATE, (uint8_t*)mpcTxMsgBuff->words, STATE_STROAGE_BUFF_MAX);
Phy_SetupNextSlot(phyInstPtr, PHY_TOR_SUSPEND, L1_200KBPS_5MS_FRAME, NULL); // any frame type is okay
else
{
l2Config.myType = L2_NODE_MEMBER;
l2Config.myId = 2;
}
else{
DBG_WARNING("Unexpected self-test command.\n");
}
break;
case MPC_MSG_TSYNC_CODE:
memcpy(mpcRxMsgBuff->words,
instPtr->rxBaseAddr + ((MPC_MSG_HEAD_LEN/8)/2),
DIV_ROUND_UP(MPC_MSG_TSYNC_LEN,8));
//FIXME:
// MPC_GetChunk(mpcRxMsgBuff, RTT_ADJ_OFFSET, RTT_ADJ_LEN, &dataChunk);
// rttRecord->rttAdj = (double)dataChunk ;
// MPC_GetChunk(mpcRxMsgBuff, TSYNC_ADJ_OFFSET, TSYNC_ADJ_LEN, &dataChunk);
// double tsyncAdj = (double)dataChunk * 0.192;
//FIXME:
// PhyWrite(TSYNC_PULS_ADJ, (uint32_t)tsyncAdj);
// MPC_GetChunk(mpcRxMsgBuff, DOPPLER_OFFSET, DOPPLER_LEN, &dataChunk);
// double dopplerAdj = (double)((dataChunk << 32)/192000000) ;
// PhyWrite(DOPPLER_ADJ, (uint32_t)dopplerAdj);
break;
default:
DBG_ERROR("Unknown message type code: %04X.\n\r", pktHeader->type);
return EPARAM;
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_FPGA_ST_OFFSET, TEST_REQ_FPGA_ST_LEN, 0x01);
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_AD_ST_OFFSET, TEST_REQ_AD_ST_LEN, 0x01);
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_RF_ST_OFFSET, TEST_REQ_RF_ST_LEN, 0x01);
MPC_SendMsg(instPtr, MPC_MSG_TEST, (uint8_t *)mpcTxMsgBuff->words, MPC_MSG_TEST_LEN);
Linklayer_Reconfig(linkInstPtr, &l2Config);
Linklayer_Start(linkInstPtr);
}
else if ((uint8_t)dataChunk == TEST_REQ_CMD_END)
{
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_FPGA_ST_OFFSET, TEST_REQ_FPGA_ST_LEN, 0x00);
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_AD_ST_OFFSET, TEST_REQ_AD_ST_LEN, 0x00);
MPC_InsertChunk(mpcTxMsgBuff, TEST_REQ_RF_ST_OFFSET, TEST_REQ_RF_ST_LEN, 0x00);
MPC_SendMsg(instPtr, MPC_MSG_TEST, (uint8_t *)mpcTxMsgBuff->words, MPC_MSG_TEST_LEN);
memset(mpcRecord, 0x00, sizeof(MPC_RECORD));
memset((uint8_t *)mpcTxMsgBuff->words, 0x00, STATE_STROAGE_BUFF_MAX);
Linklayer_Halt(linkInstPtr);
MPC_SendMsg(instPtr, MPC_MSG_STATE, (uint8_t *)mpcTxMsgBuff->words, STATE_STROAGE_BUFF_MAX);
Phy_SetupNextSlot(phyInstPtr, PHY_TOR_SUSPEND, L1_200KBPS_5MS_FRAME, NULL); // any frame type is okay
}
else
{
DBG_WARNING("Unexpected self-test command.\n");
}
break;
case MPC_MSG_TSYNC_CODE:
memcpy(mpcRxMsgBuff->words,
instPtr->rxBaseAddr + ((MPC_MSG_HEAD_LEN / 8) / 2),
DIV_ROUND_UP(MPC_MSG_TSYNC_LEN, 8));
// // FIXME:
// MPC_GetChunk(mpcRxMsgBuff, RTT_ADJ_OFFSET, RTT_ADJ_LEN, &dataChunk);
// rttRecord->rttAdj = (double)dataChunk;
// MPC_GetChunk(mpcRxMsgBuff, TSYNC_ADJ_OFFSET, TSYNC_ADJ_LEN, &dataChunk);
// double tsyncAdj = (double)dataChunk * 0.192;
// // FIXME:
// PhyWrite(TSYNC_PULS_ADJ, (uint32_t)tsyncAdj);
// MPC_GetChunk(mpcRxMsgBuff, DOPPLER_OFFSET, DOPPLER_LEN, &dataChunk);
// double dopplerAdj = (double)((dataChunk << 32) / 192000000);
// PhyWrite(DOPPLER_ADJ, (uint32_t)dopplerAdj);
break;
default:
DBG_ERROR("Unknown message type code: %04X.\n\r", pktHeader->type);
return EPARAM;
}
return SUCCESS;
}
@@ -272,18 +293,22 @@ int MPC_MsgHandler(MPC_INST* instPtr){
* error code.
*
******************************************************************************/
int MPC_SendMsg(MPC_INST* instPtr, MPC_MSG_TYPE type, uint8_t* buffer, uint32_t dlen){
int MPC_SendMsg(MPC_INST *instPtr, MPC_MSG_TYPE type, uint8_t *buffer, uint32_t dlen)
{
ASSERT(instPtr != NULL);
if(buffer == NULL ||
if (buffer == NULL ||
dlen >= instPtr->configs.msgLenMax ||
(type <= MPC_MSG_NONE || type > MPC_MSG_STATE)){
(type <= MPC_MSG_NONE || type > MPC_MSG_STATE))
{
return EPARAM;
}
if(instPtr->pcieBram.IsReady == false){
if (instPtr->pcieBram.IsReady == false)
{
return EDINVAL;
}
int Status = SUCCESS;
switch(type){
switch (type)
{
case MPC_MSG_TEST:
mpcHeader.type = MPC_MSG_TEST_CODE;
break;
@@ -294,13 +319,12 @@ int MPC_SendMsg(MPC_INST* instPtr, MPC_MSG_TYPE type, uint8_t* buffer, uint32_t
DBG_ERROR("Unknown mpc message type: %d.\n", type);
break;
}
memcpy(instPtr->txBaseAddr, &mpcHeader, MPC_MSG_HEAD_LEN/8);
memcpy(instPtr->txBaseAddr + (MPC_MSG_HEAD_LEN/8), buffer, dlen);
memcpy(instPtr->txBaseAddr, &mpcHeader, MPC_MSG_HEAD_LEN / 8);
memcpy(instPtr->txBaseAddr + (MPC_MSG_HEAD_LEN / 8), buffer, dlen);
MPC_PCIESentStart();
return Status;
}
/*****************************************************************************/
/**
* @brief Upload current state to master pc.(content detail defined in mpc
@@ -312,24 +336,27 @@ int MPC_SendMsg(MPC_INST* instPtr, MPC_MSG_TYPE type, uint8_t* buffer, uint32_t
* error code.
*
******************************************************************************/
int MPC_StateUpload(MPC_INST* instPtr , uint8_t* mgmtBuffer , uint32_t mgmtMsgCnt ,
uint8_t* svcBuffer , uint32_t svcMsgCnt , MGMT_MSG_RECORD* mgmtMsg){
int MPC_StateUpload(MPC_INST *instPtr, uint8_t *mgmtBuffer, uint32_t mgmtMsgCnt,
uint8_t *svcBuffer, uint32_t svcMsgCnt, L2_MGMT_MSG_RECORD *mgmtMsg)
{
ASSERT(instPtr != NULL);
int32_t Status = SUCCESS;
uint64_t dataChunk = 0;
if(instPtr->pcieBram.IsReady == false){
if (instPtr->pcieBram.IsReady == false)
{
return EDINVAL;
}
// Stage
switch (linkInstPtr->mainState) {
case INIT_STATE :
switch (linkInstPtr->mainState)
{
case L2_INIT_STATE:
dataChunk = STATE_STAGE_SETUP;
break;
case INTRA_SEEK_STATE:
case L2_INTRA_SEEK_STATE:
dataChunk = STATE_STAGE_RTNE;
break;
case NORMAL_STATE :
case L2_NORMAL_STATE:
dataChunk = STATE_STAGE_SVC;
break;
default:
@@ -338,10 +365,10 @@ int MPC_StateUpload(MPC_INST* instPtr , uint8_t* mgmtBuffer , uint32_t mgmtMsgC
MPC_InsertChunk(mpcTxMsgBuff, STATE_STAGE_OFFSET, STATE_STAGE_LEN, dataChunk);
// Net setup time
dataChunk = (L2_GetNextFrameNum(linkInstPtr) - linkInstPtr->netStartTime) * 1000 + L2_GetNextSlotNum(linkInstPtr) * 5 ;
dataChunk = (L2_GetNextFrameNum(linkInstPtr) + linkInstPtr->netStartTime) * 1000 + L2_GetNextSlotNum(linkInstPtr) * 5;
MPC_InsertChunk(mpcTxMsgBuff, STATE_SETUP_TIME_OFFSET, STATE_SETUP_TIME_LEN, dataChunk);
// number of nodes
dataChunk = GetNodeNum(linkInstPtr->nodeList);
dataChunk = L2_GetNodeListLen(linkInstPtr->nodeList);
MPC_InsertChunk(mpcTxMsgBuff, STATE_NUM_NODE_OFFSET, STATE_NUM_NODE_LEN, dataChunk);
// frame 1 counter
@@ -420,10 +447,10 @@ int MPC_StateUpload(MPC_INST* instPtr , uint8_t* mgmtBuffer , uint32_t mgmtMsgC
MPC_InsertChunk(mpcTxMsgBuff, STATE_FRAME_8_RECV_OFFSET, STATE_FRAME_8_RECV_LEN, dataChunk);
// Trajectory pos X
dataChunk = mgmtMsg->Longitude % 1000 ;
dataChunk = mgmtMsg->Longitude % 1000;
MPC_InsertChunk(mpcTxMsgBuff, STATE_TRAJ_X_OFFSET, STATE_TRAJ_X_LEN, dataChunk);
// Trajectory pos Y
dataChunk = mgmtMsg->Latitude % 1000 ;
dataChunk = mgmtMsg->Latitude % 1000;
MPC_InsertChunk(mpcTxMsgBuff, STATE_TRAJ_Y_OFFSET, STATE_TRAJ_Y_LEN, dataChunk);
// Trajectory alpha
dataChunk = 45;
@@ -432,10 +459,13 @@ int MPC_StateUpload(MPC_INST* instPtr , uint8_t* mgmtBuffer , uint32_t mgmtMsgC
// TODO : Currently DJ is node 1 , only Byte 1 is activate , others is useless
// Topo node 1
dataChunk = BIT(L2_GetNodeId(linkInstPtr) - 1);
if (GetNodeNum(linkInstPtr->nodeList) > 1 ) {
for(int i = 1; i <= linkInstPtr->config.netScale; i++){
if (L2_isNodeInList(linkInstPtr->nodeList, i)) {
dataChunk |= BIT(i-1);
if (L2_GetNodeListLen(linkInstPtr->nodeList) > 1)
{
for (int i = 1; i <= linkInstPtr->config.netScale; i++)
{
if (L2_isNodeInList(linkInstPtr->nodeList, i))
{
dataChunk |= BIT(i - 1);
}
}
}
@@ -459,14 +489,14 @@ int MPC_StateUpload(MPC_INST* instPtr , uint8_t* mgmtBuffer , uint32_t mgmtMsgC
MPC_InsertChunk(mpcTxMsgBuff, SVC_MSG_NUM_OFFSET, SVC_MSG_NUM_LEN, dataChunk);
// Copy msg data
size_t svcLen = mgmtMsgCnt*(72/8*6);
size_t mgmtLen = svcMsgCnt*(2040/8);
memcpy(((uint8_t*)mpcTxMsgBuff->words) + MPC_MSG_STATE_LEN/8, mgmtBuffer, svcLen);
memcpy(((uint8_t*)mpcTxMsgBuff->words) + MPC_MSG_STATE_LEN/8 + mgmtMsgCnt*(72/8*6),
svcBuffer, mgmtLen);
size_t svcLen = mgmtMsgCnt * (72 / 8 * 6);
size_t mgmtLen = svcMsgCnt * (2040 / 8);
memcpy(((uint8_t *)mpcTxMsgBuff->words) + MPC_MSG_STATE_LEN / 8, mgmtBuffer, svcLen);
memcpy(((uint8_t *)mpcTxMsgBuff->words) + MPC_MSG_STATE_LEN / 8 + mgmtMsgCnt * (72 / 8 * 6),
svcBuffer, mgmtLen);
Status = MPC_SendMsg(instPtr, MPC_MSG_STATE,(uint8_t*)mpcTxMsgBuff->words, MPC_MSG_STATE_LEN/8 + svcLen + mgmtLen);
// Status = MPC_SendMsg(instPtr, MPC_MSG_STATE,(uint8_t*)stateMsg->words, MPC_MSG_STATE_LEN/8);
Status = MPC_SendMsg(instPtr, MPC_MSG_STATE, (uint8_t *)mpcTxMsgBuff->words, MPC_MSG_STATE_LEN / 8 + svcLen + mgmtLen);
// Status = MPC_SendMsg(instPtr, MPC_MSG_STATE,(uint8_t*)stateMsg->words, MPC_MSG_STATE_LEN/8);
return Status;
}
+23 -20
View File
@@ -1,18 +1,18 @@
/*****************************************************************************/
/**
* Description: A brief description of this file
*
*
* Date: 2022-01-19 00:54
* LastEditors: Fan Hao
* LastEditTime: 2022-03-28 20:24
* Revisions: Rev 0.0
* History:
* History:
* [2022-01-19]: Initial version.
* [2022-03-28]: Add general information print function.
*
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
#ifndef MPC_CTRL_H_
@@ -30,32 +30,37 @@
#include "../phy_ctrl/phy_ctrl.h"
#include "../linklayer/linklayer814.h"
typedef struct {
typedef struct
{
const uint16_t head;
uint16_t type;
uint8_t reserve[4];
} MPC_MSG_HEADER;
typedef struct{
typedef struct
{
uint32_t bramDevId;
uint32_t msgLenMax;
} MPC_CONFIG;
typedef struct{
typedef struct
{
MPC_CONFIG configs;
XBram pcieBram;
uint8_t* txBaseAddr;
uint8_t* rxBaseAddr;
uint8_t *txBaseAddr;
uint8_t *rxBaseAddr;
} MPC_INST;
typedef enum{
typedef enum
{
MPC_MSG_NONE = 0,
MPC_MSG_TEST = 1,
MPC_MSG_STATE = 2,
} MPC_MSG_TYPE;
// FIXME: Simplify this part.
typedef struct {
typedef struct
{
uint8_t frame1Cnt;
uint8_t frame2Cnt;
uint8_t frame3Cnt;
@@ -90,17 +95,15 @@ typedef struct {
uint16_t frame8Recv;
} MPC_RECORD;
extern void MPC_PCIESentStart();
extern MPC_RECORD* mpcRecord;
extern MPC_INST* mpcInstPtr;
extern MPC_RECORD *mpcRecord;
extern MPC_INST *mpcInstPtr;
int MPC_Init(MPC_INST** instPtr, MPC_CONFIG* configPtr);
int MPC_MsgHandler(MPC_INST* instPtr);
int MPC_StateUpload(MPC_INST* instPtr , uint8_t* mgmtBuffer , uint32_t mgmtMsgCnt
, uint8_t* svcBuffer , uint32_t svcMsgCnt , MGMT_MSG_RECORD* mgmtmsg);
int MPC_SendMsg(MPC_INST* instPtr, MPC_MSG_TYPE type, uint8_t* buffer, uint32_t dlen);
int MPC_Init(MPC_INST **instPtr, MPC_CONFIG *configPtr);
int MPC_MsgHandler(MPC_INST *instPtr);
int MPC_StateUpload(MPC_INST *instPtr, uint8_t *mgmtBuffer, uint32_t mgmtMsgCnt, uint8_t *svcBuffer, uint32_t svcMsgCnt, L2_MGMT_MSG_RECORD *mgmtmsg);
int MPC_SendMsg(MPC_INST *instPtr, MPC_MSG_TYPE type, uint8_t *buffer, uint32_t dlen);
#endif //_MPC_PCIE
#endif //_MPC_CTRL
#endif //MPC_CTRL_H_
#endif // MPC_CTRL_H_
+2 -3
View File
@@ -6,8 +6,8 @@
#ifndef _MPC_MSG_DEF
#define _MPC_MSG_DEF
#define MPC_MSG_HEAD_LEN 64 //bit
#define MPC_MSG_LEN_MAX 1024 //bit
#define MPC_MSG_HEAD_LEN 64 // bit
#define MPC_MSG_LEN_MAX 1024 // bit
#define MPC_MSG_LEN_NONE UINT32_MAX
// ** Self Test Message ** //
@@ -119,7 +119,6 @@
#define STORE_ADDR_START_OFFSET 544
// ** Time SyncAdj Message ** //
// Type code
#define MPC_MSG_TSYNC_CODE 0x00FF
-371
View File
@@ -1,371 +0,0 @@
/*****************************************************************************/
/**
* Description: Antenna configuration functions.
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:15
* Revisions: Rev 0.0
* History:
* [2022-06-18]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#include <string.h>
#include <stdint.h>
#include <math.h>
#include "phy_ctrl.h"
#include "../error.h"
#define ANT_PI 3.14159265358979323846
#define ANT_COINFO_HEAD 0xAA
#define ANT_COINFO_TAIL 0xCC
#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_MODE_HIGH_POWER 0x00
#define ANT_MODE_LOWAPOWER 0x04
#define ANT_MODE_STANDBY 0x0F
#define ATN_MODE_DEFAULT (ANT_MODE_WIDE_BEAM_1 | ANT_MODE_LOWAPOWER)
#define ATN_MODE_HIGH (ANT_MODE_WIDE_BEAM_1 | ANT_MODE_HIGH_POWER)
#define DEFAULT_CENTRTAL_FREQ 0x06D7 // 26.25GHz
#define RXTXMODE_RX 0x00
#define RXTXMODE_TX 0x01
#define CALIBRMODE_NORMAL 0x00
#define CALIBRMODE_SINGLE_TR_CAL 0x01
#define MODECTRL_DEFAULT 0x00
uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS] = {0};
uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] = {1500};
uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] = {
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400
};
uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] = {1500};
uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] = { 1500, 1600, 1700,
1800, 1900, 2000, 1500, 1600, 1700, 1800, 1900 };
uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS] = {
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400
};
uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] = {
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400
};
uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS] ={ 1500, 1600, 1700, 1800, 1900, 2000, 1500, 1600 , 1700,
1800, 1900, 2000, 1500, 1600 , 1700, 1800, 1900, 2000, 1500, 1500};
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 };
// Pair by regex
// Regex: ((\{\.oaxis = [0-9]+[ ,]+\.raxis = [0-9]+[ ]*\}, ){2})
#if defined(PHY_BEAM_SET_PRESET)
ANT_ANGLE antSubnrrwPattern[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}
};
ANT_ANGLE antNrrwPattern[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}
};
#elif defined(PHY_BEAM_SET_PRESET_LSX)
ANT_ANGLE antSubnrrwPattern[NUM_ANT_SUBNRRW_PATTERN] = {
{.oaxis = 0 , .raxis =2225},{.oaxis = 96 , .raxis =850 },
{.oaxis = 135, .raxis =3075},{.oaxis = 166, .raxis =1700},
{.oaxis = 192, .raxis =325 },{.oaxis = 215, .raxis =2550},
{.oaxis = 236, .raxis =1174},{.oaxis = 255, .raxis =3399},
{.oaxis = 273, .raxis =2024},{.oaxis = 290, .raxis =649 },
{.oaxis = 306, .raxis =2874},{.oaxis = 321, .raxis =1499},
{.oaxis = 336, .raxis =124 },{.oaxis = 350, .raxis =2349},
{.oaxis = 363, .raxis =974 },{.oaxis = 377, .raxis =3199},
{.oaxis = 389, .raxis =1824},{.oaxis = 402, .raxis =449 },
{.oaxis = 414, .raxis =2674},{.oaxis = 426, .raxis =1298},
{.oaxis = 438, .raxis =3523},{.oaxis = 449, .raxis =2148},
{.oaxis = 460, .raxis =773 },{.oaxis = 471, .raxis =2998},
{.oaxis = 482, .raxis =1623},{.oaxis = 492, .raxis =248 },
{.oaxis = 503, .raxis =2473},{.oaxis = 513, .raxis =1098},
{.oaxis = 523, .raxis =3323},{.oaxis = 533, .raxis =1948},
{.oaxis = 543, .raxis =573 },{.oaxis = 553, .raxis =2798},
{.oaxis = 563, .raxis =1422},{.oaxis = 572, .raxis =47 },
{.oaxis = 581, .raxis =2272},{.oaxis = 591, .raxis =897 },
{.oaxis = 600, .raxis =3122}
};
ANT_ANGLE antNrrwPattern[NUM_ANT_NRRW_PATTERN] = {
{.oaxis = 0 , .raxis =2225},{.oaxis = 74 , .raxis =850 },
{.oaxis = 105, .raxis =3075},{.oaxis = 128, .raxis =1700},
{.oaxis = 148, .raxis =325 },{.oaxis = 166, .raxis =2550},
{.oaxis = 182, .raxis =1174},{.oaxis = 197, .raxis =3399},
{.oaxis = 210, .raxis =2024},{.oaxis = 223, .raxis =649 },
{.oaxis = 236, .raxis =2874},{.oaxis = 247, .raxis =1499},
{.oaxis = 258, .raxis =124 },{.oaxis = 269, .raxis =2349},
{.oaxis = 280, .raxis =974 },{.oaxis = 290, .raxis =3199},
{.oaxis = 299, .raxis =1824},{.oaxis = 309, .raxis =449 },
{.oaxis = 318, .raxis =2674},{.oaxis = 327, .raxis =1298},
{.oaxis = 336, .raxis =3523},{.oaxis = 344, .raxis =2148},
{.oaxis = 352, .raxis =773 },{.oaxis = 361, .raxis =2998},
{.oaxis = 369, .raxis =1623},{.oaxis = 377, .raxis =248 },
{.oaxis = 384, .raxis =2473},{.oaxis = 392, .raxis =1098},
{.oaxis = 399, .raxis =3323},{.oaxis = 407, .raxis =1948},
{.oaxis = 414, .raxis =573 },{.oaxis = 421, .raxis =2798},
{.oaxis = 428, .raxis =1422},{.oaxis = 435, .raxis =47 },
{.oaxis = 442, .raxis =2272},{.oaxis = 449, .raxis =897 },
{.oaxis = 456, .raxis =3122},{.oaxis = 462, .raxis =1747},
{.oaxis = 469, .raxis =372 },{.oaxis = 475, .raxis =2597},
{.oaxis = 482, .raxis =1222},{.oaxis = 488, .raxis =3447},
{.oaxis = 495, .raxis =2072},{.oaxis = 501, .raxis =697 },
{.oaxis = 507, .raxis =2922},{.oaxis = 513, .raxis =1546},
{.oaxis = 519, .raxis =171 },{.oaxis = 525, .raxis =2396},
{.oaxis = 531, .raxis =1021},{.oaxis = 537, .raxis =3246},
{.oaxis = 543, .raxis =1871},{.oaxis = 549, .raxis =496 },
{.oaxis = 555, .raxis =2721},{.oaxis = 561, .raxis =1346},
{.oaxis = 566, .raxis =3571},{.oaxis = 572, .raxis =2196},
{.oaxis = 578, .raxis =821 },{.oaxis = 583, .raxis =3045},
{.oaxis = 589, .raxis =1670},{.oaxis = 594, .raxis =295 },
{.oaxis = 600, .raxis =2520}
};
#else
PHY_ANT_ANGLE antSubnrrwPattern[NUM_ANT_SUBNRRW_PATTERN] = {0};
PHY_ANT_ANGLE antNrrwPattern[NUM_ANT_NRRW_PATTERN] = {0};
#endif
/*****************************************************************************/
/**
* @brief
*
* @param antCoinfoPtr
*
* @return
*
******************************************************************************/
int32_t Phy_AntCoinfoInit(PHY_ANT_CONFIG *antCoinfoPtr)
{
if (antCoinfoPtr == NULL)
{
return FAILURE;
}
antCoinfoPtr->head = ANT_COINFO_HEAD;
antCoinfoPtr->tail = ANT_COINFO_TAIL;
antCoinfoPtr->ctrlWord = 0x00;
#ifdef ANT_HIGH_POWER
antCoinfoPtr->antMode = ATN_MODE_HIGH;
#else
antCoinfoPtr->antMode = ATN_MODE_DEFAULT;
#endif
// FIXME: Dummy default value.
// off axis angle setting
antCoinfoPtr->oaxis[0] = 0;
antCoinfoPtr->oaxis[1] = 0;
// round axis angle setting
antCoinfoPtr->raxis[0] = 0;
antCoinfoPtr->raxis[1] = 0;
// ***********************
antCoinfoPtr->antFreq[0] = (uint8_t)(DEFAULT_CENTRTAL_FREQ);
antCoinfoPtr->antFreq[1] = (uint8_t)(DEFAULT_CENTRTAL_FREQ >> 8);
// FIXME: Dummy default value.
// trSelect
antCoinfoPtr->trSlect = 0;
// Antenna attenuation setting
antCoinfoPtr->antAtt = 20;
// phase setting
antCoinfoPtr->phase = 0;
// ***********************
antCoinfoPtr->rxtxMode = RXTXMODE_RX;
antCoinfoPtr->calibrMode = CALIBRMODE_NORMAL;
// FIXME: Dummy default value.
// DD enable
antCoinfoPtr->ddEn = 0;
// DD mgc
antCoinfoPtr->ddMgc = 0;
// RF mode control
antCoinfoPtr->rfCtrl = 0;
// RF MGC control
antCoinfoPtr->rfMgc = 0;
// RF channel 1&2 calibration mgc
antCoinfoPtr->rf12CalMgc = 0;
// RF channel 2&3 calibration mgc
antCoinfoPtr->rf34CalMgc = 0;
// Receive channel 1 MGC
antCoinfoPtr->rcv1Mgc = 0;
// Receive channel 2 MGC
antCoinfoPtr->rcv2Mgc = 0;
// Receive channel 3 MGC
antCoinfoPtr->rcv3Mgc = 0;
// Receive channel 4 MGC
antCoinfoPtr->rcv4Mgc = 0;
// ***********************
memset(antCoinfoPtr->dummy, 0x00, sizeof(antCoinfoPtr->dummy));
return SUCCESS;
}
int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo)
{
if(instPtr->beamWd.next == ANT_BEAM_8){
if (beamNo >= NUM_ANT_NRRW_PATTERN)
{
return FAILURE;
}
else
{
instPtr->beamNo.next = beamNo;
instPtr->antCoinfoPtr.oaxis[1] = (uint8_t)(antNrrwPattern[beamNo].oaxis);
instPtr->antCoinfoPtr.oaxis[0] = (uint8_t)((antNrrwPattern[beamNo].oaxis) >> 8);
instPtr->antCoinfoPtr.raxis[1] = (uint8_t)(antNrrwPattern[beamNo].raxis);
instPtr->antCoinfoPtr.raxis[0] = (uint8_t)((antNrrwPattern[beamNo].raxis) >> 8);
return SUCCESS;
}
}
else if(instPtr->beamWd.next == ANT_BEAM_25){
if (beamNo >= NUM_ANT_SUBNRRW_PATTERN)
{
return FAILURE;
}
else
{
instPtr->beamNo.next = beamNo;
instPtr->antCoinfoPtr.oaxis[1] = (uint8_t)(antSubnrrwPattern[beamNo].oaxis);
instPtr->antCoinfoPtr.oaxis[0] = (uint8_t)((antSubnrrwPattern[beamNo].oaxis) >> 8);
instPtr->antCoinfoPtr.raxis[1] = (uint8_t)(antSubnrrwPattern[beamNo].raxis);
instPtr->antCoinfoPtr.raxis[0] = (uint8_t)((antSubnrrwPattern[beamNo].raxis) >> 8);
return SUCCESS;
}
}
else{
// Beam number assign not support.
// Assign default angle (0,0)
instPtr->beamNo.next = 0;
instPtr->antCoinfoPtr.oaxis[1] = 0;
instPtr->antCoinfoPtr.oaxis[0] = 0;
instPtr->antCoinfoPtr.raxis[1] = 0;
instPtr->antCoinfoPtr.raxis[0] = 0;
DBG_WARNING("Using default beam number...");
return SUCCESS;
}
}
int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth)
{
uint8_t beamConfig = instPtr->antCoinfoPtr.antMode & (~ANT_MODE_BEAM_MASK);
switch (beamWidth)
{
case ANT_BEAM_120:
beamConfig |= ANT_MODE_WIDE_BEAM_3;
break;
case ANT_BEAM_60:
beamConfig |= ANT_MODE_WIDE_BEAM_2;
break;
case ANT_BEAM_25:
beamConfig |= ANT_MODE_WIDE_BEAM_1;
break;
case ANT_BEAM_8:
beamConfig |= ANT_MODE_NARROR_BEAM;
break;
default:
DBG_ERROR("Beam width code: 0x%08X is illegal.\n\r", beamWidth);
return EPARAM;
break;
}
instPtr->antCoinfoPtr.antMode = beamConfig;
instPtr->beamWd.next = beamWidth;
return SUCCESS;
}
// Common version radius double input
int32_t Phy_SetBeamAngle(PHY_INST *instPtr, double offAx, double rndAx)
{
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);
if (offAxDeg > 60)
{
DBG_ERROR("Angle out of range, off axis angle: %u(should be 0~60), round axis angle: %u(should be 0~360).",
offAxDeg, rndAxDeg);
return EPARAM;
}
offAxDeg = offAxDeg * 10;
rndAxDeg = rndAxDeg * 10;
instPtr->antCoinfoPtr.oaxis[1] = (uint8_t)offAxDeg;
instPtr->antCoinfoPtr.oaxis[0] = (uint8_t)(offAxDeg >> 8);
instPtr->antCoinfoPtr.raxis[1] = (uint8_t)rndAxDeg;
instPtr->antCoinfoPtr.raxis[0] = (uint8_t)(rndAxDeg >> 8);
return SUCCESS;
}
+446
View File
@@ -0,0 +1,446 @@
/*****************************************************************************/
/**
* Description: Antenna configuration functions.
*
* Author: Fan Hao
* Date: 2022-06-18 16:37
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:15
* Revisions: Rev 0.0
* History:
* [2022-06-18]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#include <string.h>
#include <stdint.h>
#include <math.h>
#include "phy_ctrl.h"
#include "../error.h"
#define ANT_PI 3.14159265358979323846
#define ANT_COINFO_HEAD 0xAA
#define ANT_COINFO_TAIL 0xCC
#define CTRL_WORD_DEFAULT 0x00
#define ANT_MODE_BEAM_MASK 0xF0
#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_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 ATN_ATTENUATION_MAX 0x1F
#define ATN_ATTENUATION_SKIP 0xFF
#define DEFAULT_CARRIER_FREQ 0x06D7 // 26.25GHz
#define TORMODE_RX 0x00
#define TORMODE_TX 0x01
#define TORMODE_DEFAULT 0x00
#define CALIMODE_NORMAL 0x00
#define CALIMODE_SINGLE_TR_CAL 0x01
#define RF_CTRL_DEFAULT 0x00
// Pair by regex
// Regex: (([0-9]+, ){8})
uint16_t hopPattern_Config[L1_FRAME_MAX_HOPS] =
{
0
};
uint16_t hopPattern_2KBPS_20MS[L1_FRAME_2KBPS_20MS_HOPS] =
{
1500
};
uint16_t hopPattern_2KBPS_100MS[L1_FRAME_2KBPS_100MS_HOPS] =
{
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400
};
uint16_t hopPattern_10KBPS_10MS[L1_FRAME_10KBPS_10MS_HOPS] =
{
1500
};
uint16_t hopPattern_10KBPS_20MS[L1_FRAME_10KBPS_20MS_HOPS] =
{
1500, 1600, 1700, 1800, 1900, 2000, 1500, 1600,
1700, 1800, 1900
};
uint16_t hopPattern_40KBPS_10MS[L1_FRAME_40KBPS_10MS_HOPS] =
{
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400
};
uint16_t hopPattern_40KBPS_20MS[L1_FRAME_40KBPS_20MS_HOPS] =
{
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400,
2400, 2400, 2400
};
uint16_t hopPattern_200KBPS_5MS[L1_FRAME_200KBPS_5MS_HOPS] =
{
1500, 1600, 1700, 1800, 1900, 2000, 1500, 1600,
1700, 1800, 1900, 2000, 1500, 1600, 1700, 1800,
1900, 2000, 1500, 1500
};
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
};
// Pair by regex
// Regex: ((\{\.oaxis = [0-9]+[ ,]+\.raxis = [0-9]+[ ]*\}, ){2})
#if defined(PHY_BEAM_SET_PRESET)
ANT_ANGLE antSubnrrwPattern[L1_NUM_ANT_SUBNRRW_PATTERN] = {
{.oaxis = 0 , .raxis =2225},{.oaxis = 96 , .raxis =850 },
{.oaxis = 135, .raxis =3075},{.oaxis = 166, .raxis =1700},
{.oaxis = 192, .raxis =325 },{.oaxis = 215, .raxis =2550},
{.oaxis = 236, .raxis =1174},{.oaxis = 255, .raxis =3399},
{.oaxis = 273, .raxis =2024},{.oaxis = 290, .raxis =649 },
{.oaxis = 306, .raxis =2874},{.oaxis = 321, .raxis =1499},
{.oaxis = 336, .raxis =124 },{.oaxis = 350, .raxis =2349},
{.oaxis = 363, .raxis =974 },{.oaxis = 377, .raxis =3199},
{.oaxis = 389, .raxis =1824},{.oaxis = 402, .raxis =449 },
{.oaxis = 414, .raxis =2674},{.oaxis = 426, .raxis =1298},
{.oaxis = 438, .raxis =3523},{.oaxis = 449, .raxis =2148},
{.oaxis = 460, .raxis =773 },{.oaxis = 471, .raxis =2998},
{.oaxis = 482, .raxis =1623},{.oaxis = 492, .raxis =248 },
{.oaxis = 503, .raxis =2473},{.oaxis = 513, .raxis =1098},
{.oaxis = 523, .raxis =3323},{.oaxis = 533, .raxis =1948},
{.oaxis = 543, .raxis =573 },{.oaxis = 553, .raxis =2798},
{.oaxis = 563, .raxis =1422},{.oaxis = 572, .raxis =47 },
{.oaxis = 581, .raxis =2272},{.oaxis = 591, .raxis =897 },
{.oaxis = 600, .raxis =3122}
};
ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN] = {
{.oaxis = 0 , .raxis =2225},{.oaxis = 74 , .raxis =850 },
{.oaxis = 105, .raxis =3075},{.oaxis = 128, .raxis =1700},
{.oaxis = 148, .raxis =325 },{.oaxis = 166, .raxis =2550},
{.oaxis = 182, .raxis =1174},{.oaxis = 197, .raxis =3399},
{.oaxis = 210, .raxis =2024},{.oaxis = 223, .raxis =649 },
{.oaxis = 236, .raxis =2874},{.oaxis = 247, .raxis =1499},
{.oaxis = 258, .raxis =124 },{.oaxis = 269, .raxis =2349},
{.oaxis = 280, .raxis =974 },{.oaxis = 290, .raxis =3199},
{.oaxis = 299, .raxis =1824},{.oaxis = 309, .raxis =449 },
{.oaxis = 318, .raxis =2674},{.oaxis = 327, .raxis =1298},
{.oaxis = 336, .raxis =3523},{.oaxis = 344, .raxis =2148},
{.oaxis = 352, .raxis =773 },{.oaxis = 361, .raxis =2998},
{.oaxis = 369, .raxis =1623},{.oaxis = 377, .raxis =248 },
{.oaxis = 384, .raxis =2473},{.oaxis = 392, .raxis =1098},
{.oaxis = 399, .raxis =3323},{.oaxis = 407, .raxis =1948},
{.oaxis = 414, .raxis =573 },{.oaxis = 421, .raxis =2798},
{.oaxis = 428, .raxis =1422},{.oaxis = 435, .raxis =47 },
{.oaxis = 442, .raxis =2272},{.oaxis = 449, .raxis =897 },
{.oaxis = 456, .raxis =3122},{.oaxis = 462, .raxis =1747},
{.oaxis = 469, .raxis =372 },{.oaxis = 475, .raxis =2597},
{.oaxis = 482, .raxis =1222},{.oaxis = 488, .raxis =3447},
{.oaxis = 495, .raxis =2072},{.oaxis = 501, .raxis =697 },
{.oaxis = 507, .raxis =2922},{.oaxis = 513, .raxis =1546},
{.oaxis = 519, .raxis =171 },{.oaxis = 525, .raxis =2396},
{.oaxis = 531, .raxis =1021},{.oaxis = 537, .raxis =3246},
{.oaxis = 543, .raxis =1871},{.oaxis = 549, .raxis =496 },
{.oaxis = 555, .raxis =2721},{.oaxis = 561, .raxis =1346},
{.oaxis = 566, .raxis =3571},{.oaxis = 572, .raxis =2196},
{.oaxis = 578, .raxis =821 },{.oaxis = 583, .raxis =3045},
{.oaxis = 589, .raxis =1670},{.oaxis = 594, .raxis =295 },
{.oaxis = 600, .raxis =2520}
};
#else
PHY_ANT_ANGLE antSubnrrwPattern[L1_NUM_ANT_SUBNRRW_PATTERN] =
{
0
};
PHY_ANT_ANGLE antNrrwPattern[L1_NUM_ANT_NRRW_PATTERN] =
{
0
};
#endif
/*****************************************************************************/
/**
* @brief
*
* @param antConfig
*
* @return
*
******************************************************************************/
void Phy_AntConfigInit(PHY_ANT_CONFIG *antConfig)
{
ASSERT(antConfig != NULL);
antConfig->ctrlWord = CTRL_WORD_DEFAULT;
antConfig->antMode = ATN_MODE_DEFAULT;
// FIXME: Dummy default value.
// off axis angle setting
antConfig->oaxis[0] = 0;
antConfig->oaxis[1] = 0;
// round axis angle setting
antConfig->raxis[0] = 0;
antConfig->raxis[1] = 0;
antConfig->antFreq[0] = (uint8_t)(DEFAULT_CARRIER_FREQ);
antConfig->antFreq[1] = (uint8_t)(DEFAULT_CARRIER_FREQ >> 8);
// FIXME: Dummy default value.
// trSelect
antConfig->trSelect = 0;
// Antenna attenuation setting
antConfig->antAtt = 20;
// phase setting
antConfig->phase = 0;
antConfig->torMode = TORMODE_DEFAULT;
antConfig->caliMode = CALIMODE_NORMAL;
antConfig->antReserved = 0x00;
// ***********************
// FIXME: Dummy default value.
// RF mode control
antConfig->rfCtrl = RF_CTRL_DEFAULT;
// RF frequency
antConfig->rfFreq[0] = (uint8_t)(DEFAULT_CARRIER_FREQ);
antConfig->rfFreq[1] = (uint8_t)(DEFAULT_CARRIER_FREQ >> 8);
// RF MGC control
antConfig->rfTxMgc = 0;
// RF channel 1&2 calibration mgc
antConfig->rf12CalMgc = 0;
// RF channel 2&3 calibration mgc
antConfig->rf34CalMgc = 0;
// Receive channel 1-4 MGC
antConfig->rfRxMgc = 0;
antConfig->rfReserved0 = 0x00;
antConfig->rfReserved1 = 0x00;
}
/*****************************************************************************/
/**
* @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_STANDBY:
config |= ANT_POWER_STANDBY;
break;
case PHY_ANT_MODE_POWER_LOW:
config |= ANT_POWER_LOW;
break;
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->antConfig.antMode = config;
}
/*****************************************************************************/
/**
* @brief Update antenna attenuation
*
* @param instPtr pointer to physical layer instance
* @param rxAtt rx attenuation
* @param txAtt tx attenuation
*
* @return None.
*
******************************************************************************/
void Phy_AntConfigAttenuation(PHY_INST *instPtr, uint8_t rxAtt, uint8_t txAtt)
{
ASSERT(instPtr != NULL);
if(rxAtt <= ATN_ATTENUATION_MAX)
{
instPtr->antConfig.rfRxMgc = rxAtt;
}
else if(rxAtt != ATN_ATTENUATION_SKIP)
{
DBG_ERROR("RX Attenuation exceeds range, %u.", rxAtt);
}
if(txAtt <= ATN_ATTENUATION_MAX)
{
instPtr->antConfig.rfTxMgc = txAtt;
}
else if(txAtt != ATN_ATTENUATION_SKIP)
{
DBG_ERROR("TX Attenuation exceeds range, %u.", txAtt);
}
}
/*****************************************************************************/
/**
* @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, int32_t beamNo, PHY_ANT_BEAM_WIDTH beamWidth)
{
if (beamWidth == PHY_ANT_BEAM_16)
{
if (beamNo >= L1_NUM_ANT_NRRW_PATTERN)
{
return FAILURE;
}
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 (beamWidth == 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);
return SUCCESS;
}
}
else if(beamWidth == PHY_ANT_BEAM_120)
{
// 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.raxis[0] = 0;
DBG_WARNING("Using default beam number...\n");
return SUCCESS;
}
else
{
return FAILURE;
}
}
/*****************************************************************************/
/**
* @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)
{
uint8_t beamConfig = instPtr->antConfig.antMode & (~ANT_MODE_BEAM_MASK);
switch (beamWidth)
{
case PHY_ANT_BEAM_120:
beamConfig |= ANT_BEAM_WIDE;
break;
case PHY_ANT_BEAM_60:
beamConfig |= ANT_BEAM_SUBNARROR_1;
break;
case PHY_ANT_BEAM_25:
beamConfig |= ANT_BEAM_SUBNARROR_0;
break;
case PHY_ANT_BEAM_16:
beamConfig |= ANT_BEAM_NARROR;
break;
default:
DBG_ERROR("Beam width code: 0x%08X is illegal.\n", beamWidth);
return EPARAM;
break;
}
instPtr->antConfig.antMode = beamConfig;
instPtr->beamWd.next = beamWidth;
return SUCCESS;
}
/*****************************************************************************/
/**
* @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)
{
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);
if (offAxDeg > 60)
{
DBG_ERROR("Angle out of range, off axis angle: %u (should be 0~60), round axis angle: %u (should be 0~360).\n",
offAxDeg, rndAxDeg);
return EPARAM;
}
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.raxis[0] = (uint8_t)(rndAxDeg >> 8);
return SUCCESS;
}
File diff suppressed because it is too large Load Diff
+197 -186
View File
@@ -1,11 +1,11 @@
/*****************************************************************************/
/**
* Description: Physical layer control definitions and function prototypes.
*
*
* Date: 2021-12-04 16:32
* LastEditTime: 2023-04-24 17:41
* Revisions: Rev 0.1
* History:
* 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
@@ -16,7 +16,7 @@
* - Read frame type from PL status register.
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
#ifndef PHY_CTRL_H_
@@ -24,59 +24,45 @@
/***************************** Include Files *********************************/
#include <stdint.h>
#include "phy_ctrlreg.h"
#include "phy_reg.h"
#include "../common.h"
#include "../time_ctrl/time_ctrl.h"
/************************** Constant Definitions *****************************/
#define TMWORD_FRAC_MAX 500000
#define ANTCONFIG_MAX_LEN 8192
#define TXRXDATA_MAX_LEN 2048
#define NUM_ANT_SUBNRRW_PATTERN 37
#define NUM_ANT_NRRW_PATTERN 61
#define INIT_BEAM_NO 0
#define INIT_ANT_WD ANT_BEAM_120
#define INIT_ANT_NO 0
#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 L1_FRAME_NONE_LEN UINT32_MAX// byte
#define L1_FRAME_LEN_MAX (8192/8) // byte
#define L1_FRAME_2KBPS_20MS_LEN 1 // byte
#define L1_FRAME_2KBPS_100MS_LEN 312/8 // byte
#define L1_FRAME_10KBPS_10MS_LEN 1 // byte
#define L1_FRAME_10KBPS_20MS_LEN (232/8) // byte
#define L1_FRAME_40KBPS_20MS_LEN (2152/8) // byte
#define L1_FRAME_40KBPS_10MS_LEN (712/8) // byte
#define L1_FRAME_200KBPS_5MS_LEN (2040/8) // byte
#define L1_FRAME_1M2BPS_5MS_LEN (8176/8) // byte
#define L1_FRAME_NONE_COMP UINT32_MAX // *10ns(Timer_L)
#define L1_FRAME_2KBPS_20MS_COMP 1841158 // *10ns(Timer_L)
#define L1_FRAME_2KBPS_100MS_COMP 1841158 // *10ns(Timer_L)
#define L1_FRAME_10KBPS_10MS_COMP 847733 // *10ns(Timer_L)
#define L1_FRAME_10KBPS_20MS_COMP 847733 // *10ns(Timer_L)
#define L1_FRAME_40KBPS_20MS_COMP 110667 // *10ns(Timer_L)
#define L1_FRAME_40KBPS_10MS_COMP 110667 // *10ns(Timer_L)
#define L1_FRAME_200KBPS_5MS_COMP 19725 // *10ns(Timer_L)
#define L1_FRAME_1M2BPS_5MS_COMP 19725 // *10ns(Timer_L)
#define PHY_TIME_WORD_H_MAX UINT32_MAX
#define PHY_TIME_WORD_L_MAX 0x0007A120 // 5ms/10ns
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Constant Definitions *****************************/
/**
* @name PhysicalLayer_Common_Constant
* @{
*/
#define L1_NUM_ANT_SUBNRRW_PATTERN 37
#define L1_NUM_ANT_NRRW_PATTERN 61
#define L1_INIT_BEAM_NO 0
#define L1_INIT_ANT_WD PHY_ANT_BEAM_120
#define L1_INIT_ANT_NO 0
#define L1_ANT_NUM_CH 4
#define L1_TXRXDATA_MAX_LEN 2048
#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
/** @} */
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
typedef enum {
/**
* @enum L1_FRAME_TYPE
*/
typedef enum
{
L1_NONE_FRAME = 0,
L1_2KBPS_20MS_FRAME = 1,
L1_2KBPS_100MS_FRAME = 2,
@@ -88,101 +74,135 @@ typedef enum {
L1_1M2BPS_5MS_FRAME = 8
} L1_FRAME_TYPE;
typedef struct {
/* Antenna control frame head 0xAA */
uint8_t head;
/* 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;
/* 0x00 Nromal RX, 0x01 Normal TX
* 0x11~0xA1 beam debug mode (TR duty 1%~10%)*/
uint8_t rxtxMode;
/* 0x00 Normal, 0x01 single tr calibration */
uint8_t calibrMode;
/* reserved for further use */
uint8_t reserved;
/* DD enable */
uint8_t ddEn;
/* DD mgc */
uint8_t ddMgc;
/* [7:4]RF enable: 0-On, 1-Off(Default); [3:0]Work mode: 0(default) */
uint8_t rfCtrl;
/* RF MGC control: 0~31, 1dB each LSB*/
uint8_t rfMgc;
/* 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 MGC: 0~31, 1dB each LSB */
uint8_t rcv1Mgc;
/* Receive channel 2 MGC: 0~31, 1dB each LSB */
uint8_t rcv2Mgc;
/* Receive channel 3 MGC: 0~31, 1dB each LSB */
uint8_t rcv3Mgc;
/* Receive channel 4 MGC: 0~31, 1dB each LSB */
uint8_t rcv4Mgc;
/* Antenna control frame tail 0xCC */
uint8_t tail;
uint8_t dummy[6];
/**
* @struct PHY_ANT_CONFIG
* @brief PhysicalLayer antenna config
*/
typedef struct
{
/*** Ant Control ***/
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 trSelect; ///< 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 torMode; ///< Only for debug \n
/// default 0x00
uint8_t caliMode; ///< 0x00 Normal, 0x01 single tr calibration
uint8_t antReserved; ///< reserved for further use
/*** RF Control ***/
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 rfRxMgc; ///< 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;
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;
/**
* @struct PHY_ANT_ANGLE
* @brief Describe the PhysicalLayer antenna angle
*/
typedef struct
{
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;
typedef enum {
TIME_WORD_NONE = 0,
TIME_WORD_POLL = 1,
TIME_WORD_LISTEN_TIMEOUT = 2
/**
* @enum PHY_TIME_WORD_TYPE
*/
typedef enum
{
PHY_TIME_WORD_NONE = 0,
PHY_TIME_WORD_POLL = 1,
PHY_TIME_WORD_LISTEN_TIMEOUT = 2
} PHY_TIME_WORD_TYPE;
typedef enum {
ANT_BEAM_NONE = 0,
ANT_BEAM_120 = 1,
ANT_BEAM_60 = 2,
ANT_BEAM_25 = 3,
ANT_BEAM_8 = 4
/**
* @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_16 = 4
} PHY_ANT_BEAM_WIDTH;
typedef enum {
/**
* @enum PHY_TOR_TYPE
*/
typedef enum
{
PHY_TOR_SUSPEND = 0,
PHY_TOR_TX = 1,
PHY_TOR_RX = 2
} PHY_TOR_TYPE;
typedef enum {
/**
* @enum PHY_MODE
*/
typedef enum
{
PHY_MODE_NONE = 0,
PHY_MODE_LISTEN = 1,
PHY_MODE_SCHEDULE = 2,
PHY_MODE_PULL = 3
} PHY_MODE;
typedef struct {
/**
* @enum PHY_ANT_MODE
*/
typedef enum
{
PHY_ANT_MODE_NONE = 0,
PHY_ANT_MODE_STANDBY = 1,
PHY_ANT_MODE_POWER_LOW = 2,
PHY_ANT_MODE_POWER_FULL = 3,
} PHY_ANT_MODE;
/**
* @struct PHY_RCD
* @brief Physical Layer recode buffer
*/
typedef struct
{
int32_t last;
int32_t curr;
int32_t next;
} PHY_RCD;
/**
* @struct PHY_CONFIG
* @brief struct holds all physical layer initialization parameters
*/
typedef struct
{
uint32_t devId;
uint32_t txBramId;
uint32_t rxBramId;
@@ -190,79 +210,70 @@ typedef struct {
uintptr_t baseAddr;
} PHY_CONFIG;
typedef struct {
int32_t last;
int32_t curr;
int32_t next;
} PHY_RCD;
typedef struct {
/**
* @struct PHY_INST
* @brief Physical Layer operating instance
*/
typedef struct
{
PHY_CONFIG phyCofig; // Device address configs
uintptr_t recvDataAddr;
uintptr_t sendDataAddr;
uintptr_t antConfigAddr;
bool isPhyEn; // is physical layer running
bool isAcq; // is last reception acquisition success
bool isFrameSync; // is last reception frame sync success
bool isDecode; // is last reception decode success
bool isValid; // is last reception frame data valid (crc check pass)
bool isPresetHop; // is using preset frequency hop
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
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 antCoinfoPtr;// antenna configuration pointer
PHY_ANT_CONFIG antConfig; // antenna configuration pointer
} 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[NUM_ANT_SUBNRRW_PATTERN];
extern PHY_ANT_ANGLE antNrrwPattern[NUM_ANT_NRRW_PATTERN];
/************************** Function Prototypes ******************************/
int32_t Phy_InstInit(PHY_INST** instPtr, PHY_CONFIG *phyConfig);
void Phy_Destroy(PHY_INST* instPtr);
int32_t Phy_InstInit(PHY_INST **instPtr, PHY_CONFIG *phyConfig);
void Phy_Destroy(PHY_INST *instPtr);
void Phy_Start(PHY_INST *instPtr);
void Phy_Halt(PHY_INST *instPtr);
void Phy_UpdateState(PHY_INST* instPtr);
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_Start(PHY_INST* instPtr);
void Phy_Halt(PHY_INST* instPtr);
int32_t Phy_SetMode(PHY_INST* instPtr, PHY_MODE modeCod);
int32_t Phy_SetupNextSlot(PHY_INST* instPtr, PHY_TOR_TYPE txrxMode, L1_FRAME_TYPE frameType, uint8_t* dataBuff);
void Phy_RetrieveRecvData(PHY_INST* instPtr, uint8_t* dataBuff);
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);
bool Phy_IsFrameDetected(PHY_INST *instPtr);
bool Phy_IsFrameReceived(PHY_INST *instPtr);
bool Phy_IsFrameValid(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);
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_AntCoinfoInit(PHY_ANT_CONFIG* antCoinfoPtr);
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);
double Phy_GetFreqEst(PHY_INST *instPtr);
double Phy_GetCoarseFreqEst(PHY_INST *instPtr);
double Phy_GetFineFreqEst(PHY_INST *instPtr);
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);
void Phy_AntConfigInit(PHY_ANT_CONFIG *antConfig);
void Phy_AntConfigMode(PHY_INST *instPtr, PHY_ANT_MODE mode);
void Phy_AntConfigAttenuation(PHY_INST *instPtr, uint8_t rxAtt, uint8_t txAtt);
int32_t Phy_SetBeamWidth(PHY_INST *instPtr, PHY_ANT_BEAM_WIDTH beamWidth);
int32_t Phy_SetBeamNo(PHY_INST *instPtr, int32_t beamNo, PHY_ANT_BEAM_WIDTH beamWidth);
int32_t Phy_SetBeamAngle(PHY_INST *phyInstPtr, double offAx, double rndAx);
double Phy_GetCoarseFreqEst(PHY_INST* instPtr);
void Phy_GetFrameSyncTimeStamp(PHY_INST* instPtr, TIME_WORD* frameSyncT);
void Phy_GetLastSlotStartTimeStamp(PHY_INST* instPtr, TIME_WORD* slotStart);
#endif /* PHY_CTRL_H_ */
-262
View File
@@ -1,262 +0,0 @@
/*****************************************************************************/
/**
* Description: Physical layer register definitions
*
* Author: Fan Hao
* Date: 2021-11-16 00:08
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:32
* Revisions: Rev 0.0
* 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.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef PHY_CTRLREG_H_
#define PHY_CTRLREG_H_
/***************************** Include Files *********************************/
#include "../util/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)
/************************** Constant Definitions *****************************/
/**
* Register: PHY_MAIN_CTRL
*/
#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_EN_EN 0x00000001U
#define PHY_MAIN_CTRL_EN_DSBL 0x00000000U
#define PHY_MAIN_CTRL_MODE_NONE 0x00000000U
#define PHY_MAIN_CTRL_MODE_LISTEN 0x00000100U
#define PHY_MAIN_CTRL_MODE_SCHEDULE 0x00000200U
#define PHY_MAIN_CTRL_MODE_PULL 0x00000300U
/**
* Register: TXRX_CTRL
*/
#define PHY_MODE_CTRL 0x00000004U
#define PHY_MODE_CTRL_TOR_SHIFT 0
#define PHY_MODE_CTRL_TOR_WIDTH 8
#define PHY_MODE_CTRL_TOR_MASK 0x000000FFU
#define PHY_MODE_CTRL_FRAME_SHIFT 8
#define PHY_MODE_CTRL_FRAME_WIDTH 8
#define PHY_MODE_CTRL_FRAME_MASK 0x0000FF00U
#define PHY_MODE_CTRL_CRC_SHIFT 8
#define PHY_MODE_CTRL_CRC_WIDTH 16
#define PHY_MODE_CTRL_CRC_MASK 0x00FF0000U
#define PHY_MODE_CTRL_TOR_SUSPEND 0x00000000U
#define PHY_MODE_CTRL_TOR_TX 0x00000001U
#define PHY_MODE_CTRL_TOR_RX 0x00000002U
#define PHY_MODE_CTRL_FRAME_NONE 0x00000000U
#define PHY_MODE_CTRL_FRAME_2KBPS_20MS 0x00000100U
#define PHY_MODE_CTRL_FRAME_2KBPS_100MS 0x00000200U
#define PHY_MODE_CTRL_FRAME_10KBPS_10MS 0x00000300U // Initial Scan Frame
#define PHY_MODE_CTRL_FRAME_10KBPS_20MS 0x00000400U // Benchmark Frame
#define PHY_MODE_CTRL_FRAME_40KBPS_20MS 0x00000500U
#define PHY_MODE_CTRL_FRAME_40KBPS_10MS 0x00000600U
#define PHY_MODE_CTRL_FRAME_200KBPS_5MS 0x00000700U // 2-Way ACQ Frame, Management Frame, Service Frame
#define PHY_MODE_CTRL_FRAME_1M2BPS_5MS 0x00000800U // Bistatic Synthetic Aperture Radar Frame
#define PHY_MODE_CTRL_CRC_EN 0x00010000U
#define PHY_MODE_CTRL_CRC_DSBL 0x00000000U
/**
* Register: POLLTIME_L
*/
#define POLLTIME_L 0x00000008U
#define POLLTIME_L_SHIFT 0
#define POLLTIME_L_WIDTH 32
#define POLLTIME_L_MASK 0xFFFFFFFFU
/**
* Register: POLLTIME_H
*/
#define POLLTIME_H 0x0000000CU
#define POLLTIME_H_SHIFT 0
#define POLLTIME_H_WIDTH 32
#define POLLTIME_H_MASK 0xFFFFFFFFU
/**
* Register: TIMEOUT_L
*/
#define LISTENTIMEOUT_L 0x00000010U
#define LISTENTIMEOUT_L_SHIFT 0
#define LISTENTIMEOUT_L_WIDTH 32
#define LISTENTIMEOUT_L_MASK 0xFFFFFFFFU
/**
* Register: TIMEOUT_H
*/
#define LISTENTIMEOUT_H 0x00000014U
#define LISTENTIMEOUT_H_SHIFT 0
#define LISTENTIMEOUT_H_WIDTH 32
#define LISTENTIMEOUT_H_MASK 0xFFFFFFFFU
/**
* Register: ANT_CTRL
*/
#define ANT_CONFIG 0x00000018U
#define ANT_CONFIG_OFFSET_SHIFT 0
#define ANT_CONFIG_OFFSET_WIDTH 16
#define ANT_CONFIG_OFFSET_MASK 0x0000FFFFU
#define ANT_CONFIG_LEN_SHIFT 16
#define ANT_CONFIG_LEN_WIDTH 8
#define ANT_CONFIG_LEN_MASK 0x00FF0000U
#define ANT_CONFIG_NUM_SHIFT 24
#define ANT_CONFIG_NUM_WIDTH 8
#define ANT_CONFIG_NUM_MASK 0xFF000000U
/**
* Register: SEND_DATA_CMD
*/
#define SEND_DATA_CMD 0x0000001CU
#define SEND_DATA_CMD_SHIFT 0
#define SEND_DATA_CMD_WIDTH 32
#define SEND_DATA_CMD_MASK 0xFFFFFFFFU
#define SEND_DATA_CMD_LEN_SHIFT 0
#define SEND_DATA_CMD_LEN_WIDTH 16
#define SEND_DATA_CMD_LEN_MASK 0x0000FFFFU
#define SEND_DATA_CMD_OFFSET_SHIFT 16
#define SEND_DATA_CMD_OFFSET_WIDTH 16
#define SEND_DATA_CMD_OFFSET_MASK 0xFFFF0000U
/**
* Register: SEND_CONFIG_CMD
*/
#define SLOT_CMD 0x00000020U
#define SLOT_CMD_SHIFT 0
#define SLOT_CMD_WIDTH 32
#define SLOT_CMD_MASK 0xFFFFFFFFU
#define SLOT_CMD_KEY 0x434D442EU
/**
* Register: TXRX_STATE
*/
#define TXRX_STATE 0x00000024U
#define TXRX_STATE_ACQ_SHIFT 0
#define TXRX_STATE_ACQ_WIDTH 8
#define TXRX_STATE_ACQ_MASK 0x000000FFU
#define TXRX_STATE_ACQ_SUCCESS 0x00000001U
#define TXRX_STATE_ACQ_FAIL 0x00000002U
#define TXRX_STATE_FSYNC_SHIFT 8
#define TXRX_STATE_FSYNC_WIDTH 8
#define TXRX_STATE_FSYNC_MASK 0x0000FF00U
#define TXRX_STATE_FSYNC_SUCCESS 0x00000100U
#define TXRX_STATE_FSYNC_FAIL 0x00000200U
#define TXRX_STATE_DECODE_SHIFT 16
#define TXRX_STATE_DECODE_WIDTH 8
#define TXRX_STATE_DECODE_MASK 0x00FF0000U
#define TXRX_STATE_DECODE_SUCCESS 0x00010000U
#define TXRX_STATE_DECODE_FAIL 0x00020000U
#define TXRX_STATE_CRC_SHIFT 24
#define TXRX_STATE_CRC_WIDTH 8
#define TXRX_STATE_CRC_MASK 0xFF000000U
#define TXRX_STATE_CRC_OK 0x01000000U
#define TXRX_STATE_CRC_ERROR 0x02000000U
/**
* Register: RECVDATA_STATE
*/
#define RECVDATA_STATE 0x00000028U
#define RECVDATA_STATE_LEN_SHIFT 0
#define RECVDATA_STATE_LEN_WIDTH 16
#define RECVDATA_STATE_LEN_MASK 0x0000FFFFU
#define RECVDATA_STATE_OFFSET_SHIFT 16
#define RECVDATA_STATE_OFFSET_WIDTH 16
#define RECVDATA_STATE_OFFSET_MASK 0xFFFF0000U
/**
* Register: FSTIME_L
*/
#define FSTIME_L 0x000002CU
#define FSTIME_L_SHIFT 0
#define FSTIME_L_WIDTH 32
#define FSTIME_L_MASK 0xFFFFFFFFU
/**
* Register: FSTIME_INT1
*/
#define FSTIME_H 0x0000030U
#define FSTIME_H_SHIFT 0
#define FSTIME_H_WIDTH 32
#define FSTIME_H_MASK 0xFFFFFFFFU
/**
* Register: TM_TARGET_L
*/
#define TM_TARGET_L 0x0000064U
#define TM_TARGET_L_SHIFT 0
#define TM_TARGET_L_WIDTH 32
#define TM_TARGET_L_MASK 0xFFFFFFFFU
/**
* Register: TM_TARGET_H
*/
#define TM_TARGET_H 0x0000038U
#define TM_TARGET_H_SHIFT 0
#define TM_TARGET_H_WIDTH 32
#define TM_TARGET_H_MASK 0xFFFFFFFFU
/**
* Register: COASEFREQEST
*/
#define COASE_FREQEST 0x0000003CU
#define COASE_FREQEST_ACQ_SHIFT 0
#define COASE_FREQEST_ACQ_WIDTH 8
#define COASE_FREQEST_ACQ_MASK 0x000000FFU
#define COASE_FREQEST_SYNC_SHIFT 0
#define COASE_FREQEST_SYNC_WIDTH 16
#define COASE_FREQEST_SYNC_MASK 0x000FF00U
/**
* Register: FINE_FREQEST
*/
#define FINE_FREQEST 0x00000040U
#define FINE_FREQEST_SHIFT 0
#define FINE_FREQEST_WIDTH 32
#define FINE_FREQEST_MASK 0xFFFFFFFFU
/**
* Register: BEAM_SELECT
*/
#define BEAM_SELECT_INDEX 0x00000044U
#define BEAM_SELECT_INDEX_SHIFT 0
#define BEAM_SELECT_INDEX_WIDTH 32
#define BEAM_SELECT_INDEX_MASK 0xFFFFFFFFU
/**
* Register: BEAM_SELECT
*/
#define BEAM_AXIS 0x00000044U
#define BEAM_AXIS_EL_SHIFT 0
#define BEAM_AXIS_EL_WIDTH 16
#define BEAM_AXIS_EL_MASK 0x0000FFFFU
#define BEAM_AXIS_AZ_SHIFT 16
#define BEAM_AXIS_AZ_WIDTH 16
#define BEAM_AXIS_AZ_MASK 0xFFFF0000U
// Reserved.
#endif /* PHY_CTRLREG_H_ */
+277
View File
@@ -0,0 +1,277 @@
/*****************************************************************************/
/**
* Description: Physical layer register definitions
*
* Author: Fan Hao
* Date: 2021-11-16 00:08
* LastEditors: Fan Hao
* LastEditTime: 2022-06-18 17:32
* Revisions: Rev 0.0
* 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.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
#ifndef PHY_REG_H_
#define PHY_REG_H_
/***************************** Include Files *********************************/
#include "../util/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)
/************************** Constant Definitions *****************************/
/**
* Register: PHY_MAIN_CTRL
*/
#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_EN_EN 0x00000001U
#define PHY_MAIN_CTRL_EN_DSBL 0x00000000U
#define PHY_MAIN_CTRL_MODE_NONE 0x00000000U
#define PHY_MAIN_CTRL_MODE_LISTEN 0x00000100U
#define PHY_MAIN_CTRL_MODE_SCHEDULE 0x00000200U
#define PHY_MAIN_CTRL_MODE_PULL 0x00000300U
/**
* Register: TXRX_CTRL
*/
#define PHY_MODE_CTRL 0x00000004U
#define PHY_MODE_CTRL_TOR_SHIFT 0
#define PHY_MODE_CTRL_TOR_WIDTH 8
#define PHY_MODE_CTRL_TOR_MASK 0x000000FFU
#define PHY_MODE_CTRL_FRAME_SHIFT 8
#define PHY_MODE_CTRL_FRAME_WIDTH 8
#define PHY_MODE_CTRL_FRAME_MASK 0x0000FF00U
#define PHY_MODE_CTRL_CRC_SHIFT 8
#define PHY_MODE_CTRL_CRC_WIDTH 16
#define PHY_MODE_CTRL_CRC_MASK 0x00FF0000U
#define PHY_MODE_CTRL_TOR_SUSPEND 0x00000000U
#define PHY_MODE_CTRL_TOR_TX 0x00000001U
#define PHY_MODE_CTRL_TOR_RX 0x00000002U
#define PHY_MODE_CTRL_FRAME_NONE 0x00000000U
#define PHY_MODE_CTRL_FRAME_2KBPS_20MS 0x00000100U
#define PHY_MODE_CTRL_FRAME_2KBPS_100MS 0x00000200U
#define PHY_MODE_CTRL_FRAME_10KBPS_10MS 0x00000300U // Initial Scan Frame
#define PHY_MODE_CTRL_FRAME_10KBPS_20MS 0x00000400U // Benchmark Frame
#define PHY_MODE_CTRL_FRAME_40KBPS_20MS 0x00000500U
#define PHY_MODE_CTRL_FRAME_40KBPS_10MS 0x00000600U
#define PHY_MODE_CTRL_FRAME_200KBPS_5MS 0x00000700U // 2-Way ACQ Frame, Management Frame, Service Frame
#define PHY_MODE_CTRL_FRAME_1M2BPS_5MS 0x00000800U // Bistatic Synthetic Aperture Radar Frame
#define PHY_MODE_CTRL_CRC_EN 0x00010000U
#define PHY_MODE_CTRL_CRC_DSBL 0x00000000U
/**
* Register: POLLTIME_L
*/
#define POLLTIME_L 0x00000008U
#define POLLTIME_L_SHIFT 0
#define POLLTIME_L_WIDTH 32
#define POLLTIME_L_MASK 0xFFFFFFFFU
/**
* Register: POLLTIME_H
*/
#define POLLTIME_H 0x0000000CU
#define POLLTIME_H_SHIFT 0
#define POLLTIME_H_WIDTH 32
#define POLLTIME_H_MASK 0xFFFFFFFFU
/**
* Register: TIMEOUT_L
*/
#define LISTENTIMEOUT_L 0x00000010U
#define LISTENTIMEOUT_L_SHIFT 0
#define LISTENTIMEOUT_L_WIDTH 32
#define LISTENTIMEOUT_L_MASK 0xFFFFFFFFU
/**
* Register: TIMEOUT_H
*/
#define LISTENTIMEOUT_H 0x00000014U
#define LISTENTIMEOUT_H_SHIFT 0
#define LISTENTIMEOUT_H_WIDTH 32
#define LISTENTIMEOUT_H_MASK 0xFFFFFFFFU
/**
* Register: ANT_CTRL
*/
#define ANT_CONFIG 0x00000018U
#define ANT_CONFIG_OFFSET_SHIFT 0
#define ANT_CONFIG_OFFSET_WIDTH 16
#define ANT_CONFIG_OFFSET_MASK 0x0000FFFFU
#define ANT_CONFIG_LEN_SHIFT 16
#define ANT_CONFIG_LEN_WIDTH 8
#define ANT_CONFIG_LEN_MASK 0x00FF0000U
#define ANT_CONFIG_NUM_SHIFT 24
#define ANT_CONFIG_NUM_WIDTH 8
#define ANT_CONFIG_NUM_MASK 0xFF000000U
/**
* Register: SEND_DATA_CMD
*/
#define SEND_DATA_CMD 0x0000001CU
#define SEND_DATA_CMD_SHIFT 0
#define SEND_DATA_CMD_WIDTH 32
#define SEND_DATA_CMD_MASK 0xFFFFFFFFU
#define SEND_DATA_CMD_LEN_SHIFT 0
#define SEND_DATA_CMD_LEN_WIDTH 16
#define SEND_DATA_CMD_LEN_MASK 0x0000FFFFU
#define SEND_DATA_CMD_OFFSET_SHIFT 16
#define SEND_DATA_CMD_OFFSET_WIDTH 16
#define SEND_DATA_CMD_OFFSET_MASK 0xFFFF0000U
/**
* Register: SLOT_CONFIG_CMD
*/
#define SLOT_CMD 0x00000020U
#define SLOT_CMD_SHIFT 0
#define SLOT_CMD_WIDTH 32
#define SLOT_CMD_MASK 0xFFFFFFFFU
#define SLOT_CMD_KEY 0x434D442EU
/**
* Register: TXRX_STATE
*/
#define TXRX_STATE 0x00000024U
#define TXRX_STATE_ACQ_SHIFT 0
#define TXRX_STATE_ACQ_WIDTH 8
#define TXRX_STATE_ACQ_MASK 0x000000FFU
#define TXRX_STATE_ACQ_SUCCESS 0x00000001U
#define TXRX_STATE_ACQ_FAIL 0x00000002U
#define TXRX_STATE_FSYNC_SHIFT 8
#define TXRX_STATE_FSYNC_WIDTH 8
#define TXRX_STATE_FSYNC_MASK 0x0000FF00U
#define TXRX_STATE_FSYNC_SUCCESS 0x00000100U
#define TXRX_STATE_FSYNC_FAIL 0x00000200U
#define TXRX_STATE_DECODE_SHIFT 16
#define TXRX_STATE_DECODE_WIDTH 8
#define TXRX_STATE_DECODE_MASK 0x00FF0000U
#define TXRX_STATE_DECODE_SUCCESS 0x00010000U
#define TXRX_STATE_DECODE_FAIL 0x00020000U
#define TXRX_STATE_CRC_SHIFT 24
#define TXRX_STATE_CRC_WIDTH 8
#define TXRX_STATE_CRC_MASK 0xFF000000U
#define TXRX_STATE_CRC_OK 0x01000000U
#define TXRX_STATE_CRC_ERROR 0x02000000U
/**
* Register: RECVDATA_STATE
*/
#define RECVDATA_STATE 0x00000028U
#define RECVDATA_STATE_LEN_SHIFT 0
#define RECVDATA_STATE_LEN_WIDTH 16
#define RECVDATA_STATE_LEN_MASK 0x0000FFFFU
#define RECVDATA_STATE_OFFSET_SHIFT 16
#define RECVDATA_STATE_OFFSET_WIDTH 16
#define RECVDATA_STATE_OFFSET_MASK 0xFFFF0000U
/**
* Register: FSTIME_L
*/
#define FSTIME_L 0x0000002CU
#define FSTIME_L_SHIFT 0
#define FSTIME_L_WIDTH 32
#define FSTIME_L_MASK 0xFFFFFFFFU
/**
* Register: FSTIME_INT1
*/
#define FSTIME_H 0x00000030U
#define FSTIME_H_SHIFT 0
#define FSTIME_H_WIDTH 32
#define FSTIME_H_MASK 0xFFFFFFFFU
/**
* Register: TM_TARGET_L
*/
#define TM_TARGET_L 0x00000064U
#define TM_TARGET_L_SHIFT 0
#define TM_TARGET_L_WIDTH 32
#define TM_TARGET_L_MASK 0xFFFFFFFFU
/**
* Register: TM_TARGET_H
*/
#define TM_TARGET_H 0x00000038U
#define TM_TARGET_H_SHIFT 0
#define TM_TARGET_H_WIDTH 32
#define TM_TARGET_H_MASK 0xFFFFFFFFU
/**
* Register: COASEFREQEST
*/
#define COASE_FREQEST 0x0000003CU
#define COASE_FREQEST_ACQ_SHIFT 0
#define COASE_FREQEST_ACQ_WIDTH 8
#define COASE_FREQEST_ACQ_MASK 0x000000FFU
#define COASE_FREQEST_SYNC_SHIFT 8
#define COASE_FREQEST_SYNC_WIDTH 8
#define COASE_FREQEST_SYNC_MASK 0x0000FF00U
#define COASE_TYPE_SHIFT 16
#define COASE_TYPE_WIDTH 8
#define COASE_TYPE_MASK 0x00FF0000U
#define COASE_TYPE_2KBPS_20MS 0x00010000U
#define COASE_TYPE_2KBPS_100MS 0x00020000U
#define COASE_TYPE_10KBPS_10MS 0x00030000U
#define COASE_TYPE_10KBPS_20MS 0x00040000U
#define COASE_TYPE_40KBPS_20MS 0x00050000U
#define COASE_TYPE_40KBPS_10MS 0x00060000U
#define COASE_TYPE_200KBPS_5MS 0x00070000U
#define COASE_TYPE_1M2BPS_5MS 0x00080000U
/**
* Register: FINE_FREQEST
*/
#define FINE_FREQEST 0x00000040U
#define FINE_FREQEST_VAL_SHIFT 0
#define FINE_FREQEST_VAL_WIDTH 24
#define FINE_FREQEST_VAL_MASK 0x00FFFFFFU
#define FINE_FREQEST_SIGN_SHIFT 24
#define FINE_FREQEST_SIGN_WIDTH 8
#define FINE_FREQEST_SIGN_MASK 0xFF000000U
#define FINE_FREQEST_SIGN_POS 0x00000000U
#define FINE_FREQEST_SIGN_NEG 0x01000000U
/**
* Register: BEAM_SELECT
*/
#define BEAM_SELECT_INDEX 0x00000044U
#define BEAM_SELECT_INDEX_SHIFT 0
#define BEAM_SELECT_INDEX_WIDTH 32
#define BEAM_SELECT_INDEX_MASK 0xFFFFFFFFU
/**
* Register: BEAM_AXIS
*/
#define BEAM_AXIS 0x00000044U
#define BEAM_AXIS_EL_SHIFT 0
#define BEAM_AXIS_EL_WIDTH 16
#define BEAM_AXIS_EL_MASK 0x0000FFFFU
#define BEAM_AXIS_AZ_SHIFT 16
#define BEAM_AXIS_AZ_WIDTH 16
#define BEAM_AXIS_AZ_MASK 0xFFFF0000U
// Reserved.
#endif /* PHY_REG_H_ */
+99 -44
View File
@@ -1,19 +1,18 @@
/*****************************************************************************/
/**
* Description: Time sync implementation file.
*
*
* Author: Author's name
* Date: 2021-12-04 16:32
* Date: 2023-12-20 16:32
* LastEditors: FanHao
* LastEditTime: 2022-07-10 20:43
* LastEditTime: 2023-12-22 20:43
* Revisions: Rev 0.0
* History:
* [2022-07-10]: New branch for Dijian.
* [2021-12-04]: Initial version.
*
* History:
* [2023-12-20]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
/***************************** Include Files *********************************/
@@ -24,22 +23,22 @@
#include "../util/util.h"
/************************** Constant Definitions *****************************/
#define VERSION_REG 0x00000004
#define TIME_INT_REG 0x00000008
#define TIME_FRAC_REG 0x0000000C
#define TIME_RESET 0x00000010
#define PRESET_HIGH 0x00000014
#define PRESET_LOW 0x00000018
#define TIME_ADJ_INT 0x0000001C
#define TIME_ADJ_FRAC 0x00000020
#define TIME_ADJ_TRIG 0x00000024
#define CNTSTEP_OPT 0x00000028
#define VERSION_REG 0x00000004
#define TIME_INT_REG 0x00000008
#define TIME_FRAC_REG 0x0000000C
#define TIME_RESET 0x00000010
#define PRESET_HIGH 0x00000014
#define PRESET_LOW 0x00000018
#define TIME_ADJ_INT 0x0000001C
#define TIME_ADJ_FRAC 0x00000020
#define TIME_ADJ_MODE 0x00000024
#define TIME_ADJ_TRIG 0x00000028
#define CNTSTEP_OPT 0x0000002c
#define TM_RESET_CODE 0x5253542E
#define TM_RESET_CODE 0x5253542E
/***************** 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)
#define TMC_Read(instPtr, addr) IO_In32(instPtr->config.baseAddr + addr)
#define TMC_Write(instPtr, addr, value) IO_Out32(instPtr->config.baseAddr + addr, value)
/*****************************************************************************/
/**
@@ -52,22 +51,45 @@
* FAILURE Initialization failed
*
******************************************************************************/
int32_t TimeCtrl_Init(TIMECTRL_INST **instPtr, TIMECTRL_CONFIG *config){
int32_t TimeCtrl_Init(TMC_INST **instPtr, TMC_CONFIG *config)
{
ASSERT(config != NULL);
ASSERT(instPtr != NULL);
(*instPtr) = malloc(sizeof(TIMECTRL_INST));
memcpy(&((*instPtr)->config), config, sizeof(TIMECTRL_CONFIG));
(*instPtr) = malloc(sizeof(TMC_INST));
memcpy(&((*instPtr)->config), config, sizeof(TMC_CONFIG));
(*instPtr)->modelVer = TMC_Read((*instPtr), VERSION_REG);
return SUCCESS;
}
void TimeCtrl_Destroy(TIMECTRL_INST *instPtr) {
/*****************************************************************************/
/**
* @brief Completely destroy time control instance.
*
* @param instPtr a pointer to time controller instance
*
* @return NONE
*
******************************************************************************/
void TimeCtrl_Destroy(TMC_INST *instPtr)
{
free(instPtr);
}
uint32_t TimeCtrl_GetVersion(TIMECTRL_INST *instPtr){
/*****************************************************************************/
/**
* @brief Read time controller version register.
*
* @param instPtr a pointer to time controller instance
*
* @return timer controller version.
*
******************************************************************************/
uint32_t TimeCtrl_GetVersion(TMC_INST *instPtr)
{
ASSERT(instPtr != NULL);
return TMC_Read(instPtr, VERSION_REG);
}
/*****************************************************************************/
/**
* @brief Apply a reset process to time controller
@@ -78,12 +100,12 @@ uint32_t TimeCtrl_GetVersion(TIMECTRL_INST *instPtr){
* FAILURE Initialization failed
*
******************************************************************************/
void TimeCtrl_Reset(TIMECTRL_INST *instPtr){
void TimeCtrl_Reset(TMC_INST *instPtr)
{
ASSERT(instPtr != NULL);
TMC_Write(instPtr, CNTSTEP_OPT, TM_RESET_CODE);
}
/*****************************************************************************/
/**
* @brief Assert time controller reset high
@@ -93,12 +115,12 @@ void TimeCtrl_Reset(TIMECTRL_INST *instPtr){
* @return NONE
*
******************************************************************************/
void TimeCtrl_ResetHigh(TIMECTRL_INST *instPtr){
void TimeCtrl_ResetHigh(TMC_INST *instPtr)
{
ASSERT(instPtr != NULL);
// TODO:
}
/*****************************************************************************/
/**
* @brief Assert time controller reset low
@@ -108,12 +130,12 @@ void TimeCtrl_ResetHigh(TIMECTRL_INST *instPtr){
* @return NONE
*
******************************************************************************/
void TimeCtrl_ResetLow(TIMECTRL_INST *instPtr){
void TimeCtrl_ResetLow(TMC_INST *instPtr)
{
ASSERT(instPtr != NULL);
// TODO:
}
/*****************************************************************************/
/**
* @brief Get current time integer value.
@@ -123,7 +145,8 @@ void TimeCtrl_ResetLow(TIMECTRL_INST *instPtr){
* @return integer value
*
******************************************************************************/
inline TIME_INT TimeCtrl_GetIntCnt(TIMECTRL_INST *instPtr){
inline TIME_INT TimeCtrl_GetIntCnt(TMC_INST *instPtr)
{
ASSERT(instPtr != NULL);
return TMC_Read(instPtr, TIME_INT_REG);
}
@@ -137,7 +160,8 @@ inline TIME_INT TimeCtrl_GetIntCnt(TIMECTRL_INST *instPtr){
* @return fractional value
*
******************************************************************************/
inline TIME_FRAC TimeCtrl_GetFracCnt(TIMECTRL_INST *instPtr){
inline TIME_FRAC TimeCtrl_GetFracCnt(TMC_INST *instPtr)
{
ASSERT(instPtr != NULL);
return TMC_Read(instPtr, TIME_FRAC_REG);
}
@@ -152,7 +176,8 @@ inline TIME_FRAC TimeCtrl_GetFracCnt(TIMECTRL_INST *instPtr){
* @return NONE
*
******************************************************************************/
void TimeCtrl_GetCurrentTime(TIMECTRL_INST *instPtr, TIME_WORD* tmWord){
void TimeCtrl_GetCurrentTime(TMC_INST *instPtr, TIME_WORD *tmWord)
{
ASSERT(instPtr != NULL);
ASSERT(tmWord != NULL);
tmWord->frac_part = TMC_Read(instPtr, TIME_FRAC_REG);
@@ -169,13 +194,13 @@ void TimeCtrl_GetCurrentTime(TIMECTRL_INST *instPtr, TIME_WORD* tmWord){
* @return NONE.
*
******************************************************************************/
void TimeCtrl_GetCurrentStep(TIMECTRL_INST *instPtr, TIME_FRAC* tmFrac) {
void TimeCtrl_GetCurrentStep(TMC_INST *instPtr, TIME_FRAC *tmFrac)
{
ASSERT(instPtr != NULL);
ASSERT(tmFrac != NULL);
*tmFrac = TMC_Read(instPtr, CNTSTEP_OPT);
}
/*****************************************************************************/
/**
* @brief Set a new optimal adjustment value to the counter step.
@@ -187,20 +212,24 @@ void TimeCtrl_GetCurrentStep(TIMECTRL_INST *instPtr, TIME_FRAC* tmFrac) {
* @return NONE.
*
******************************************************************************/
void TimeCtrl_TimeAdjust(TIMECTRL_INST *instPtr, const TIME_WORD* tmWord, TIMECTRL_ADJ_TYPE type){
void TimeCtrl_TimeAdjust(TMC_INST *instPtr, const TIME_WORD *tmWord, TIMECTRL_ADJ_TYPE type)
{
ASSERT(instPtr != NULL);
ASSERT(tmWord != NULL);
if(type < TM_ADJ_ADD || TM_ADJ_ADD > TM_ADJ_SET){
if (type < TM_ADJ_ADD || TM_ADJ_ADD > TM_ADJ_SET)
{
DBG_ERROR("Unsupported adjustment type: %d", type);
return;
}
if(((int32_t)tmWord->frac_part) > COUNTE_FRAC_MAX ) {
DBG_ERROR("Invalid fractional value 0x%08X (should <= 0x%08X).\n",
tmWord->frac_part, COUNTE_FRAC_MAX);
if (((int32_t)tmWord->frac_part) > TIME_FRAC_MAX || ((int32_t)tmWord->frac_part) < -TIME_FRAC_MAX)
{
DBG_WARNING("Invalid fractional value %d (should between %d~%d)\n",
tmWord->frac_part, -TIME_FRAC_MAX, TIME_FRAC_MAX);
return;
}
TMC_Write(instPtr, TIME_ADJ_FRAC, tmWord->frac_part);
TMC_Write(instPtr, TIME_ADJ_INT, tmWord->int_part);
TMC_Write(instPtr, TIME_ADJ_MODE, type);
TMC_Write(instPtr, TIME_ADJ_TRIG, type);
}
@@ -214,8 +243,34 @@ void TimeCtrl_TimeAdjust(TIMECTRL_INST *instPtr, const TIME_WORD* tmWord, TIMECT
* @return NONE.
*
******************************************************************************/
void TimeCtrl_SetOptimizeStep(TIMECTRL_INST* instPtr, TIME_FRAC* tmFrac) {
void TimeCtrl_SetOptimizeStep(TMC_INST *instPtr, TIME_FRAC *tmFrac)
{
ASSERT(instPtr != NULL);
ASSERT(tmFrac != NULL);
TMC_Write(instPtr, CNTSTEP_OPT, *tmFrac);
}
/*****************************************************************************/
/**
* @brief Calculate b - a.
*
* @param a time stamp A
* @param b time stamp B
* @param gap t round
*
* @return NONE
*
******************************************************************************/
void TimeCtrl_CalculateTimeGap(const TIME_WORD *a, const TIME_WORD *b, TIME_WORD *gap)
{
ASSERT(a != NULL);
ASSERT(b != NULL);
ASSERT(gap != NULL);
uint64_t timeDiff;
timeDiff = (uint64_t)b->frac_part;
timeDiff += ((uint64_t)b->int_part) * TIME_FRAC_MAX;
timeDiff -= ((uint64_t)a->int_part) * TIME_FRAC_MAX;
timeDiff -= (uint64_t)a->frac_part;
gap->frac_part = (TIME_FRAC)(timeDiff % TIME_FRAC_MAX);
gap->frac_part = (TIME_INT)(timeDiff / TIME_FRAC_MAX);
}
+33 -30
View File
@@ -1,18 +1,17 @@
/*****************************************************************************/
/**
* Description: A simplified version of timesync for datalink 814 (Dijian)
*
* Date: 2021-12-04 16:32
*
* Date: 2023-12-20-04 16:32
* LastEditors: Fan Hao
* LastEditTime: 2022-07-06 16:32
* LastEditTime: 2023-12-20 16:32
* Revisions: Rev 0.0
* History:
* [2022-07-06]: Initial version.
* [2021-12-04]: Initial version.
*
* History:
* [2023-12-20]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
#ifndef TIME_CTRL_H_
@@ -21,10 +20,11 @@
/***************************** Include Files *********************************/
#include <stdint.h>
/************************** Constant Definitions *****************************/
#define COUNTE_FRAC_MAX 500000 // how many 10ns in a 5ms
#define TIME_FRAC_MAX 500000 // how many 10ns in a 5ms
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
typedef enum {
typedef enum
{
TM_ADJ_NONE = 0,
TM_ADJ_ADD = 1,
TM_ADJ_SET = 2
@@ -33,39 +33,42 @@ typedef enum {
typedef uint32_t TIME_FRAC;
typedef uint32_t TIME_INT;
typedef struct {
typedef struct
{
/* 5ms each LSB */
TIME_INT int_part;
/* 10ns each LSB */
TIME_FRAC frac_part;
} TIME_WORD;
typedef struct {
typedef struct
{
uintptr_t baseAddr;
uint32_t reset; //time for reset (unit: us)
} TIMECTRL_CONFIG;
uint32_t reset; // time for reset (unit: us)
} TMC_CONFIG;
typedef struct {
TIMECTRL_CONFIG config;
typedef struct
{
TMC_CONFIG config;
uint32_t modelVer;
} TIMECTRL_INST;
} TMC_INST;
/************************** Function Prototypes ******************************/
int32_t TimeCtrl_Init(TIMECTRL_INST **instPtr, TIMECTRL_CONFIG *config);
uint32_t TimeCtrl_GetVersion(TIMECTRL_INST *instPtr);
void TimeCtrl_Destroy(TIMECTRL_INST *instPtr);
void TimeCtrl_Reset(TIMECTRL_INST *instPtr);
void TimeCtrl_ResetLow(TIMECTRL_INST *instPtr);
void TimeCtrl_ResetHigh(TIMECTRL_INST *instPtr);
int32_t TimeCtrl_Init(TMC_INST **instPtr, TMC_CONFIG *config);
uint32_t TimeCtrl_GetVersion(TMC_INST *instPtr);
void TimeCtrl_Destroy(TMC_INST *instPtr);
void TimeCtrl_Reset(TMC_INST *instPtr);
void TimeCtrl_ResetLow(TMC_INST *instPtr);
void TimeCtrl_ResetHigh(TMC_INST *instPtr);
TIME_INT TimeCtrl_GetIntCnt(TIMECTRL_INST *instPtr);
TIME_FRAC TimeCtrl_GetFracCnt(TIMECTRL_INST *instPtr);
TIME_INT TimeCtrl_GetIntCnt(TMC_INST *instPtr);
TIME_FRAC TimeCtrl_GetFracCnt(TMC_INST *instPtr);
void TimeCtrl_GetCurrentTime(TIMECTRL_INST *instPtr, TIME_WORD* tmWord);
void TimeCtrl_GetCurrentStep(TIMECTRL_INST *instPtr, TIME_FRAC* tmFrac);
void TimeCtrl_SetOptimizeStep(TIMECTRL_INST *instPtr, TIME_FRAC* tmFrac);
void TimeCtrl_TimeAdjust(TIMECTRL_INST *instPtr, const TIME_WORD* tmWord, TIMECTRL_ADJ_TYPE type);
void TimeCtrl_GetCurrentTime(TMC_INST *instPtr, TIME_WORD *tmWord);
void TimeCtrl_GetCurrentStep(TMC_INST *instPtr, TIME_FRAC *tmFrac);
void TimeCtrl_SetOptimizeStep(TMC_INST *instPtr, TIME_FRAC *tmFrac);
void TimeCtrl_TimeAdjust(TMC_INST *instPtr, const TIME_WORD *tmWord, TIMECTRL_ADJ_TYPE type);
void TimeCtrl_CalculateTimeGap(const TIME_WORD *a, const TIME_WORD *b, TIME_WORD *gap);
#endif /* TIME_SYNC_H_ */
@@ -1,15 +1,15 @@
/*****************************************************************************/
/**
* Description: A simple circular FIFO bounded queue
*
*
* Author: Fan Hao
* Date: 2023-02-23 10:29
* LastEditors: Fan Hao
* LastEditTime: 2023-02-23 13:18
* Revisions: Rev 0.0
* History:
* 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
@@ -27,29 +27,31 @@
* 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.
******************************************************************************/
******************************************************************************/
#include "circ_queue.h"
#include "common.h"
#include "../common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
inline bool isCircQueueFull(CIRC_QUEUE *queue){
ASSERT(queue != NULL);
return ((queue)->nelts == (queue)->bounds);
}
inline bool isCircQueueEmpty(CIRC_QUEUE *queue){
ASSERT(queue != NULL);
return ((queue)->nelts == 0);
}
void CircQueueFree(CIRC_QUEUE * queue)
inline bool isCircQueueFull(CIRC_QUEUE *queue)
{
ASSERT(queue != NULL);
if (queue->data) free(queue->data);
return ((queue)->nelts == (queue)->bounds);
}
inline bool isCircQueueEmpty(CIRC_QUEUE *queue)
{
ASSERT(queue != NULL);
return ((queue)->nelts == 0);
}
void CircQueueFree(CIRC_QUEUE *queue)
{
ASSERT(queue != NULL);
if (queue->data)
free(queue->data);
free(queue);
}
@@ -61,15 +63,17 @@ bool CircQueueCreate(CIRC_QUEUE **q, uint32_t queueCapacity)
ASSERT(q != NULL);
CIRC_QUEUE *queue;
queue = malloc(sizeof(CIRC_QUEUE));
if (!queue) {
if (!queue)
{
return false;
}
*q = queue;
memset(queue, 0, sizeof(CIRC_QUEUE));
/* Set all the data in the queue to NULL */
queue->data = malloc(queueCapacity * sizeof(void*));
if(queue->data == NULL){
queue->data = malloc(queueCapacity * sizeof(void *));
if (queue->data == NULL)
{
goto error;
}
queue->bounds = queueCapacity;
@@ -89,13 +93,15 @@ bool CircQueuePush(CIRC_QUEUE *queue, void *data)
{
ASSERT(queue != NULL);
if (isCircQueueFull(queue)) {
if (isCircQueueFull(queue))
{
return false;
}
queue->data[queue->in] = data;
queue->in++;
if (queue->in >= queue->bounds) {
if (queue->in >= queue->bounds)
{
queue->in -= queue->bounds;
}
queue->nelts++;
@@ -104,28 +110,31 @@ bool CircQueuePush(CIRC_QUEUE *queue, void *data)
}
/**
* Return current number of element in queue.
* Return current number of element in queue.
*/
inline uint32_t CircQueueSize(CIRC_QUEUE *queue) {
inline uint32_t CircQueueSize(CIRC_QUEUE *queue)
{
return queue->nelts;
}
/**
* Retrieves the next item from the queue.
* Retrieves the next item from the queue.
*/
bool CircQueuePop(CIRC_QUEUE *queue, void **data)
{
ASSERT(queue != NULL);
if (isCircQueueEmpty(queue)) {
return false;
}
if (isCircQueueEmpty(queue))
{
return false;
}
*data = queue->data[queue->out];
queue->nelts--;
queue->out++;
if (queue->out >= queue->bounds) {
if (queue->out >= queue->bounds)
{
queue->out -= queue->bounds;
}
return true;
+342
View File
@@ -0,0 +1,342 @@
#ifndef LIST_MALLOC
#define LIST_MALLOC malloc
#endif
#ifndef LIST_FREE
#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.
*/
clist_node_t *
clist_node_new(void *val)
{
clist_node_t *self;
if (!(self = LIST_MALLOC(sizeof(clist_node_t))))
return NULL;
self->prev = NULL;
self->next = NULL;
self->val = val;
return self;
}
/*
* Allocate a new clist_t. NULL on failure.
*/
clist_t *
clist_new(void)
{
clist_t *self;
if (!(self = LIST_MALLOC(sizeof(clist_t))))
return NULL;
self->head = NULL;
self->tail = NULL;
self->free = NULL;
self->compare = NULL;
self->len = 0;
return self;
}
/*
* Remove all the node in list.
* @self: Pointer to the list
*/
void clist_clear(clist_t *self)
{
clist_node_t *next;
clist_node_t *curr = self->head;
while (curr != NULL)
{
next = curr->next;
if (self->free)
self->free(curr->val);
LIST_FREE(curr);
curr = next;
}
self->len = 0;
self->head = NULL;
}
/*
* Free the list.
* @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
*/
clist_node_t *
clist_rpush(clist_t *self, clist_node_t *node)
{
if (!node)
return NULL;
if (self->len)
{
node->prev = self->tail;
node->next = NULL;
self->tail->next = node;
self->tail = node;
}
else
{
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* Return / detach the last node in the list, or NULL.
* @self: Pointer to the list for popping node
*/
clist_node_t *
clist_rpop(clist_t *self)
{
if (!self->len)
return NULL;
clist_node_t *node = self->tail;
if (--self->len)
{
(self->tail = node->prev)->next = NULL;
}
else
{
self->tail = self->head = NULL;
}
node->next = node->prev = NULL;
return node;
}
/*
* Return / detach the first node in the list, or NULL.
* @self: Pointer to the list for popping node
*/
clist_node_t *
clist_lpop(clist_t *self)
{
if (!self->len)
return NULL;
clist_node_t *node = self->head;
if (--self->len)
{
(self->head = node->next)->prev = NULL;
}
else
{
self->head = self->tail = NULL;
}
node->next = node->prev = NULL;
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
*/
clist_node_t *
clist_lpush(clist_t *self, clist_node_t *node)
{
if (!node)
return NULL;
if (self->len)
{
node->next = self->head;
node->prev = NULL;
self->head->prev = node;
self->head = node;
}
else
{
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* Return the node associated to val or NULL.
* @self: Pointer to the list for finding given value
* @val: Value to find
*/
clist_node_t *
clist_find(clist_t *self, void *val)
{
clist_iterator_t *it = clist_iterator_new(self, LIST_HEAD);
clist_node_t *node;
while ((node = clist_iterator_next(it)))
{
if (self->compare)
{
if (self->compare(val, node->val) == 0)
{
clist_iterator_destroy(it);
return node;
}
}
else
{
if (val == node->val)
{
clist_iterator_destroy(it);
return node;
}
}
}
clist_iterator_destroy(it);
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
*/
clist_node_t *
clist_at(clist_t *self, int index)
{
clist_direction_t direction = LIST_HEAD;
if (index < 0)
{
direction = LIST_TAIL;
index = ~index;
}
if ((unsigned)index < self->len)
{
clist_iterator_t *it = clist_iterator_new(self, direction);
clist_node_t *node = clist_iterator_next(it);
while (index--)
node = clist_iterator_next(it);
clist_iterator_destroy(it);
return node;
}
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
*/
void clist_remove(clist_t *self, clist_node_t *node)
{
node->prev
? (node->prev->next = node->next)
: (self->head = node->next);
node->next
? (node->next->prev = node->prev)
: (self->tail = node->prev);
if (self->free)
self->free(node->val);
LIST_FREE(node);
--self->len;
}
/*
* Allocate a new clist_iterator_t. NULL on failure.
* Accepts a direction, which may be LIST_HEAD or LIST_TAIL.
*/
clist_iterator_t *
clist_iterator_new(clist_t *list, clist_direction_t direction)
{
clist_node_t *node = direction == LIST_HEAD
? list->head
: list->tail;
return clist_iterator_new_from_node(node, direction);
}
/*
* Allocate a new clist_iterator_t with the given start
* node. NULL on failure.
*/
clist_iterator_t *
clist_iterator_new_from_node(clist_node_t *node, clist_direction_t direction)
{
clist_iterator_t *self;
if (!(self = LIST_MALLOC(sizeof(clist_iterator_t))))
return NULL;
self->next = node;
self->direction = direction;
return self;
}
/*
* Return the next clist_node_t or NULL when no more
* nodes remain in the list.
*/
clist_node_t *
clist_iterator_next(clist_iterator_t *self)
{
clist_node_t *curr = self->next;
if (curr)
{
self->next = self->direction == LIST_HEAD
? curr->next
: curr->prev;
}
return curr;
}
/*
* Free the list iterator.
*/
void clist_iterator_destroy(clist_iterator_t *self)
{
LIST_FREE(self);
self = NULL;
}
+118
View File
@@ -0,0 +1,118 @@
//
// clist.h
//
// Copyright (c) 2010 TJ Holowaychuk <[email protected]>
//
#ifndef __CLIST_H__
#define __CLIST_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdlib.h>
#include <stdint.h>
/*
* clist_t iterator direction.
*/
typedef enum
{
LIST_HEAD,
LIST_TAIL
} clist_direction_t;
/*
* clist_t node struct.
*/
typedef struct clist_node
{
struct clist_node *prev;
struct clist_node *next;
void *val;
} clist_node_t;
/*
* 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_t;
/*
* clist_t iterator struct.
*/
typedef struct
{
clist_node_t *next;
clist_direction_t direction;
} clist_iterator_t;
// Node prototypes.
clist_node_t *
clist_node_new(void *val);
// clist_t prototypes.
clist_t *
clist_new(void);
clist_node_t *
clist_rpush(clist_t *self, clist_node_t *node);
clist_node_t *
clist_lpush(clist_t *self, clist_node_t *node);
clist_node_t *
clist_find(clist_t *self, void *val);
clist_node_t *
clist_at(clist_t *self, int index);
clist_node_t *
clist_rpop(clist_t *self);
clist_node_t *
clist_lpop(clist_t *self);
void
clist_remove(clist_t *self, clist_node_t *node);
void
clist_clear(clist_t *self);
void
clist_destroy(clist_t *self);
// clist_t iterator prototypes.
clist_iterator_t *
clist_iterator_new(clist_t *list, clist_direction_t direction);
clist_iterator_t *
clist_iterator_new_from_node(clist_node_t *node, clist_direction_t direction);
clist_node_t *
clist_iterator_next(clist_iterator_t *self);
void
clist_iterator_destroy(clist_iterator_t *self);
#ifdef __cplusplus
}
#endif
#endif /* __CLIBS_LIST_H__ */
+102 -80
View File
@@ -1,19 +1,19 @@
/*****************************************************************************/
/**
* Description: CRC implementation file
*
*
* Author: Hao Fan
* Date: 2021-11-16 00:50
* LastEditors: Hao Fan
* LastEditTime: 2022-07-17 20:53
* Revisions: Rev 0.0
* History:
* History:
* [2022-07-17]: Add CRC16_0x8005 CRC8_0x31.
* [2022-01-06]: Initial verion (Basic CRC-16).
*
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
#include "util.h"
@@ -22,7 +22,8 @@
#ifdef __CRC_LSB
// CRC-16-CCITT G(X)=X16+X12+X5+1
// Reversed
static const uint16_t crc16_1021_lsb_lut[256] = {
static const uint16_t crc16_1021_lsb_lut[256] =
{
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
@@ -58,7 +59,8 @@ static const uint16_t crc16_1021_lsb_lut[256] = {
};
// CRC-16-MAXIM G(X)=X16+X15+X2+1
const uint16_t crc16_8005_lsb_lut[256] = {
const uint16_t crc16_8005_lsb_lut[256] =
{
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
@@ -94,7 +96,8 @@ const uint16_t crc16_8005_lsb_lut[256] = {
};
// CRC-8-MAXIM G(X)=X8+X5+X4+1
const uint8_t crc8_31_lsb_lut[256] = {
const uint8_t crc8_31_lsb_lut[256] =
{
0x00, 0x5E, 0xBC, 0xE2, 0x61, 0x3F, 0xDD, 0x83,
0xC2, 0x9C, 0x7E, 0x20, 0xA3, 0xFD, 0x1F, 0x41,
0x9D, 0xC3, 0x21, 0x7F, 0xFC, 0xA2, 0x40, 0x1E,
@@ -130,7 +133,8 @@ const uint8_t crc8_31_lsb_lut[256] = {
};
#else
// CRC-16-CCITT G(X)=X16+X12+X5+1
static const uint16_t crc16_1021_msb_lut[256] = {
static const uint16_t crc16_1021_msb_lut[256] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
@@ -166,7 +170,8 @@ static const uint16_t crc16_1021_msb_lut[256] = {
};
// CRC-16-MAXIM G(X)=X16+X15+X2+1
const uint16_t crc16_8005_msb_lut[256] = {
const uint16_t crc16_8005_msb_lut[256] =
{
0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011,
0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022,
0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072,
@@ -202,7 +207,8 @@ const uint16_t crc16_8005_msb_lut[256] = {
};
// CRC-8-MAXIM G(X)=X8+X5+X4+1
const uint8_t crc8_31_msb_lut[256] = {
const uint8_t crc8_31_msb_lut[256] =
{
0x00, 0x31, 0x62, 0x53, 0xC4, 0xF5, 0xA6, 0x97,
0xB9, 0x88, 0xDB, 0xEA, 0x7D, 0x4C, 0x1F, 0x2E,
0x43, 0x72, 0x21, 0x10, 0x87, 0xB6, 0xE5, 0xD4,
@@ -258,86 +264,91 @@ for(int i = 0; i < sizeof(dataBuff); i++)
/*****************************************************************************/
/**
* @brief CRC8 generator
*
*
* @param buffPtr data buffer pointer.
* @param dataLen data length
* @param poly polynomials of crc
* @param crcVal a pointer to store generated crc value
*
*
* @return SUCCESS
* FAILURE
*
*
******************************************************************************/
int crc8_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint8_t* crcVal) {
int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal)
{
uint8_t crc = CRC8_INIT;
const uint8_t* crc_lut = NULL;
const uint8_t *crc_lut = NULL;
switch(poly){
switch (poly)
{
#ifdef __CRC_LSB
case 0x31:
crc_lut = crc8_31_lsb_lut;
break;
default:
return FAILURE;
case 0x31:
crc_lut = crc8_31_lsb_lut;
break;
default:
return FAILURE;
#else
case 0x31:
crc_lut = crc8_31_msb_lut;
break;
default:
return FAILURE;
case 0x31:
crc_lut = crc8_31_msb_lut;
break;
default:
return FAILURE;
#endif
}
for(int i = 0; i < dataLen; i++){
crc = crc_lut[(uint8_t)(crc^buffPtr[i])];
for (int i = 0; i < dataLen; i++)
{
crc = crc_lut[(uint8_t)(crc ^ buffPtr[i])];
}
*crcVal = crc;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief CRC16 generator
*
*
* @param buffPtr data buffer pointer.
* @param dataLen data length
* @param poly polynomials of crc
* @param crcVal a pointer to store generated crc value
*
*
* @return SUCCESS
* FAILURE
*
*
******************************************************************************/
int crc16_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint16_t* crcVal) {
int crc16_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint16_t *crcVal)
{
uint16_t crc = CRC16_INIT;
const uint16_t* crc_lut = NULL;
switch(poly){
const uint16_t *crc_lut = NULL;
switch (poly)
{
#ifdef __CRC_LSB
case 0x8005:
crc_lut = crc16_8005_lsb_lut;
break;
case 0x1021:
crc_lut = crc16_1021_lsb_lut;
break;
default:
return FAILURE;
case 0x8005:
crc_lut = crc16_8005_lsb_lut;
break;
case 0x1021:
crc_lut = crc16_1021_lsb_lut;
break;
default:
return FAILURE;
#else
case 0x8005:
crc_lut = crc16_8005_msb_lut;
break;
case 0x1021:
crc_lut = crc16_1021_msb_lut;
break;
default:
return FAILURE;
case 0x8005:
crc_lut = crc16_8005_msb_lut;
break;
case 0x1021:
crc_lut = crc16_1021_msb_lut;
break;
default:
return FAILURE;
#endif
}
for(int i = 0; i < dataLen; i++){
for (int i = 0; i < dataLen; i++)
{
#ifdef __CRC_LSB
crc = (crc>>8) ^ crc_lut[(uint8_t)(crc^buffPtr[i])];
crc = (crc >> 8) ^ crc_lut[(uint8_t)(crc ^ buffPtr[i])];
#else
crc = (crc<<8) ^ crc_lut[(uint8_t)((crc >> 8)^buffPtr[i])];
crc = (crc << 8) ^ crc_lut[(uint8_t)((crc >> 8) ^ buffPtr[i])];
#endif
}
*crcVal = crc;
@@ -347,71 +358,82 @@ int crc16_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint16_t* crcVa
/*****************************************************************************/
/**
* @brief CRC8 compare cheker
*
*
* @param buffPtr data buffer pointer.
* @param dataLen data length
* @param crcOffset byte offset of crc stored position.
* @param poly polynomials of crc
*
*
* @return true
* false
*
******************************************************************************/
bool crc8_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly) {
*
******************************************************************************/
bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly)
{
int Status = SUCCESS;
uint8_t crc_comp;
uint8_t crc;
if (dataLen == 0) {
return false;
}
if (dataLen == 0)
{
return false;
}
crc_comp = (uint8_t)(*(buffPtr + crcOffset));
Status = crc8_gen(buffPtr, dataLen, poly, &crc);
if(Status == SUCCESS){
if (crc == crc_comp) {
if (Status == SUCCESS)
{
if (crc == crc_comp)
{
return true;
}
else {
else
{
return false;
}
}
else{
else
{
return false;
}
}
/*****************************************************************************/
/**
* @brief CRC16 compare cheker
*
*
* @param buffPtr data buffer pointer.
* @param dataLen data length
* @param crcOffset byte offset of crc stored position.
* @param poly polynomials of crc
*
*
* @return true
* fasle
*
******************************************************************************/
bool crc16_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly) {
*
******************************************************************************/
bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly)
{
int Status = SUCCESS;
uint16_t crc_comp;
uint16_t crc;
if (dataLen == 0) {
return false;
}
if (dataLen == 0)
{
return false;
}
crc_comp = (uint16_t)(*(buffPtr + crcOffset));
crc_comp |= (uint16_t)((*(buffPtr + crcOffset + 1)) << 8);
Status = crc16_gen(buffPtr, dataLen, poly, &crc);
if(Status == SUCCESS){
if (crc == crc_comp) {
if (Status == SUCCESS)
{
if (crc == crc_comp)
{
return true;
}
else {
else
{
return false;
}
}
else{
else
{
return false;
}
}
-301
View File
@@ -1,301 +0,0 @@
#ifndef LIST_MALLOC
#define LIST_MALLOC malloc
#endif
#ifndef LIST_FREE
#define LIST_FREE free
#endif
//
// list.c
//
// Copyright (c) 2010 TJ Holowaychuk <[email protected]>
//
#include "list.h"
/*
* Allocates a new list_node_t. NULL on failure.
*/
list_node_t *
list_node_new(void *val) {
list_node_t *self;
if (!(self = LIST_MALLOC(sizeof(list_node_t))))
return NULL;
self->prev = NULL;
self->next = NULL;
self->val = val;
return self;
}
/*
* Allocate a new list_t. NULL on failure.
*/
list_t *
list_new(void) {
list_t *self;
if (!(self = LIST_MALLOC(sizeof(list_t))))
return NULL;
self->head = NULL;
self->tail = NULL;
self->free = NULL;
self->match = NULL;
self->len = 0;
return self;
}
/*
* Remove all the node in list.
* @self: Pointer to the list
*/
void
list_clear(list_t *self) {
uint32_t len = self->len;
list_node_t *next;
list_node_t *curr = self->head;
while (len) {
next = curr->next;
if (self->free) self->free(curr->val);
LIST_FREE(curr);
curr = next;
len--;
}
}
/*
* Free the list.
* @self: Pointer to the list
*/
void
list_destroy(list_t *self) {
list_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
*/
list_node_t *
list_rpush(list_t *self, list_node_t *node) {
if (!node) return NULL;
if (self->len) {
node->prev = self->tail;
node->next = NULL;
self->tail->next = node;
self->tail = node;
} else {
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* Return / detach the last node in the list, or NULL.
* @self: Pointer to the list for popping node
*/
list_node_t *
list_rpop(list_t *self) {
if (!self->len) return NULL;
list_node_t *node = self->tail;
if (--self->len) {
(self->tail = node->prev)->next = NULL;
} else {
self->tail = self->head = NULL;
}
node->next = node->prev = NULL;
return node;
}
/*
* Return / detach the first node in the list, or NULL.
* @self: Pointer to the list for popping node
*/
list_node_t *
list_lpop(list_t *self) {
if (!self->len) return NULL;
list_node_t *node = self->head;
if (--self->len) {
(self->head = node->next)->prev = NULL;
} else {
self->head = self->tail = NULL;
}
node->next = node->prev = NULL;
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
*/
list_node_t *
list_lpush(list_t *self, list_node_t *node) {
if (!node) return NULL;
if (self->len) {
node->next = self->head;
node->prev = NULL;
self->head->prev = node;
self->head = node;
} else {
self->head = self->tail = node;
node->prev = node->next = NULL;
}
++self->len;
return node;
}
/*
* Return the node associated to val or NULL.
* @self: Pointer to the list for finding given value
* @val: Value to find
*/
list_node_t *
list_find(list_t *self, void *val) {
list_iterator_t *it = list_iterator_new(self, LIST_HEAD);
list_node_t *node;
while ((node = list_iterator_next(it))) {
if (self->match) {
if (self->match(val, node->val)) {
list_iterator_destroy(it);
return node;
}
} else {
if (val == node->val) {
list_iterator_destroy(it);
return node;
}
}
}
list_iterator_destroy(it);
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
*/
list_node_t *
list_at(list_t *self, int index) {
list_direction_t direction = LIST_HEAD;
if (index < 0) {
direction = LIST_TAIL;
index = ~index;
}
if ((unsigned)index < self->len) {
list_iterator_t *it = list_iterator_new(self, direction);
list_node_t *node = list_iterator_next(it);
while (index--) node = list_iterator_next(it);
list_iterator_destroy(it);
return node;
}
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
*/
void
list_remove(list_t *self, list_node_t *node) {
node->prev
? (node->prev->next = node->next)
: (self->head = node->next);
node->next
? (node->next->prev = node->prev)
: (self->tail = node->prev);
if (self->free) self->free(node->val);
LIST_FREE(node);
--self->len;
}
/*
* Allocate a new list_iterator_t. NULL on failure.
* Accepts a direction, which may be LIST_HEAD or LIST_TAIL.
*/
list_iterator_t *
list_iterator_new(list_t *list, list_direction_t direction) {
list_node_t *node = direction == LIST_HEAD
? list->head
: list->tail;
return list_iterator_new_from_node(node, direction);
}
/*
* Allocate a new list_iterator_t with the given start
* node. NULL on failure.
*/
list_iterator_t *
list_iterator_new_from_node(list_node_t *node, list_direction_t direction) {
list_iterator_t *self;
if (!(self = LIST_MALLOC(sizeof(list_iterator_t))))
return NULL;
self->next = node;
self->direction = direction;
return self;
}
/*
* Return the next list_node_t or NULL when no more
* nodes remain in the list.
*/
list_node_t *
list_iterator_next(list_iterator_t *self) {
list_node_t *curr = self->next;
if (curr) {
self->next = self->direction == LIST_HEAD
? curr->next
: curr->prev;
}
return curr;
}
/*
* Free the list iterator.
*/
void
list_iterator_destroy(list_iterator_t *self) {
LIST_FREE(self);
self = NULL;
}
-114
View File
@@ -1,114 +0,0 @@
//
// list.h
//
// Copyright (c) 2010 TJ Holowaychuk <[email protected]>
//
#ifndef __LIST_H__
#define __LIST_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
/*
* list_t iterator direction.
*/
typedef enum {
LIST_HEAD,
LIST_TAIL
} list_direction_t;
/*
* list_t node struct.
*/
typedef struct list_node {
struct list_node *prev;
struct list_node *next;
void *val;
} list_node_t;
/*
* list_t struct.
*/
typedef struct {
list_node_t *head;
list_node_t *tail;
uint32_t len;
void (*free)(void *val);
bool (*match)(void *a, void *b);
} list_t;
/*
* list_t iterator struct.
*/
typedef struct {
list_node_t *next;
list_direction_t direction;
} list_iterator_t;
// Node prototypes.
list_node_t *
list_node_new(void *val);
// list_t prototypes.
list_t *
list_new(void);
list_node_t *
list_rpush(list_t *self, list_node_t *node);
list_node_t *
list_lpush(list_t *self, list_node_t *node);
list_node_t *
list_find(list_t *self, void *val);
list_node_t *
list_at(list_t *self, int index);
list_node_t *
list_rpop(list_t *self);
list_node_t *
list_lpop(list_t *self);
void
list_remove(list_t *self, list_node_t *node);
void
list_clear(list_t *self);
void
list_destroy(list_t *self);
// list_t iterator prototypes.
list_iterator_t *
list_iterator_new(list_t *list, list_direction_t direction);
list_iterator_t *
list_iterator_new_from_node(list_node_t *node, list_direction_t direction);
list_node_t *
list_iterator_next(list_iterator_t *self);
void
list_iterator_destroy(list_iterator_t *self);
#ifdef __cplusplus
}
#endif
#endif /* __CLIBS_LIST_H__ */
+56 -39
View File
@@ -11,7 +11,8 @@
/************************** Functions Implementation **************************/
/******************************************************************************/
#ifdef __BITSWAP_TABLE
static uint8_t byte_flipLR[256] = {
static uint8_t byte_flipLR[256] =
{
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
@@ -47,16 +48,19 @@ static uint8_t byte_flipLR[256] = {
};
#endif
inline void IO_Out32(uintptr_t addr, uint32_t value){
inline void IO_Out32(uintptr_t addr, uint32_t value)
{
volatile uint32_t *localAddr = (volatile uint32_t *)addr;
*localAddr = value;
}
inline uint32_t IO_In32(uintptr_t addr){
return *(volatile uint32_t*) addr;
inline uint32_t IO_In32(uintptr_t addr)
{
return *(volatile uint32_t *)addr;
}
uint8_t byte_bit_swap(uint8_t byte){
uint8_t byte_bit_swap(uint8_t byte)
{
#ifdef __BITSWAP_TABLE
return byte_flipLR[byte];
#else
@@ -64,38 +68,42 @@ uint8_t byte_bit_swap(uint8_t byte){
#endif
}
uint32_t word_bit_swap(uint32_t word){
uint32_t word_bit_swap(uint32_t word)
{
#ifdef __BITSWAP_TABLE
uint32_t rv_word = (byte_flipLR[word & 0xff] << 24) |
(byte_flipLR[(word >> 8) & 0xff] << 16) |
(byte_flipLR[(word >> 16) & 0xff] << 8) |
(byte_flipLR[(word >> 24) & 0xff]);
(byte_flipLR[(word >> 8) & 0xff] << 16) |
(byte_flipLR[(word >> 16) & 0xff] << 8) |
(byte_flipLR[(word >> 24) & 0xff]);
return rv_word;
#else
word = (((word & 0xaaaaaaaa) >> 1) | ((word & 0x55555555) << 1));
word = (((word & 0xcccccccc) >> 2) | ((word & 0x33333333) << 2));
word = (((word & 0xf0f0f0f0) >> 4) | ((word & 0x0f0f0f0f) << 4));
word = (((word & 0xff00ff00) >> 8) | ((word & 0x00ff00ff) << 8));
return((word >> 16) | (word << 16));
return ((word >> 16) | (word << 16));
#endif
}
uint32_t count_ones(uint32_t word){
uint32_t count_ones(uint32_t word)
{
#ifdef __GNUC__
return __builtin_popcount(word);
#else
uint32_t one_count = 0;
while (word) {
while (word)
{
if (word & 0x00000001)
one_count ++;
one_count++;
word >>= 1;
}
return one_count;
#endif
}
double fix2double(int32_t val, uint8_t frac_bits){
return (((double)val)/(BIT(frac_bits)));
double fix2double(int32_t val, uint8_t frac_bits)
{
return (((double)val) / (BIT(frac_bits)));
}
/**
@@ -104,20 +112,23 @@ double fix2double(int32_t val, uint8_t frac_bits){
uint32_t find_first_set_bit(uint32_t word)
{
#ifdef __GNUC__
if(word != 0){
if (word != 0)
{
return __builtin_ctz(word);
}
else{
else
{
return 32;
}
#else
uint32_t first_set_bit = 0;
while (word) {
while (word)
{
if (word & 0x1)
return first_set_bit;
word >>= 1;
first_set_bit ++;
first_set_bit++;
}
return 32;
@@ -130,21 +141,24 @@ uint32_t find_first_set_bit(uint32_t word)
uint32_t find_last_set_bit(uint32_t word)
{
#ifdef __GNUC__
if(word != 0){
return (31-__builtin_clz(word));
if (word != 0)
{
return (31 - __builtin_clz(word));
}
else{
else
{
return 32;
}
#else
uint32_t bit = 0;
uint32_t last_set_bit = 32;
while (word) {
while (word)
{
if (word & 0x1)
last_set_bit = bit;
word >>= 1;
bit ++;
bit++;
}
return last_set_bit;
@@ -155,15 +169,17 @@ uint32_t find_last_set_bit(uint32_t word)
* Locate the closest element in an array.
*/
uint32_t find_closest(int32_t val,
const int32_t *array,
uint32_t size)
const int32_t *array,
uint32_t size)
{
int32_t diff = abs(array[0] - val);
uint32_t ret = 0;
uint32_t i;
for (i = 1; i < size; i++) {
if (abs(array[i] - val) < diff) {
for (i = 1; i < size; i++)
{
if (abs(array[i] - val) < diff)
{
diff = abs(array[i] - val);
ret = i;
}
@@ -200,7 +216,7 @@ int32_t log_base_2(uint32_t x)
* Find greatest common divisor of the given two numbers.
*/
uint32_t greatest_common_divisor(uint32_t a,
uint32_t b)
uint32_t b)
{
uint32_t div;
uint32_t common_div = 1;
@@ -219,11 +235,11 @@ uint32_t greatest_common_divisor(uint32_t a,
* Calculate best rational approximation for a given fraction.
*/
void rational_best_approximation(uint32_t given_numerator,
uint32_t given_denominator,
uint32_t max_numerator,
uint32_t max_denominator,
uint32_t *best_numerator,
uint32_t *best_denominator)
uint32_t given_denominator,
uint32_t max_numerator,
uint32_t max_denominator,
uint32_t *best_numerator,
uint32_t *best_denominator)
{
uint32_t gcd;
@@ -233,7 +249,8 @@ void rational_best_approximation(uint32_t given_numerator,
*best_denominator = given_denominator / gcd;
if ((*best_numerator > max_numerator) ||
(*best_denominator > max_denominator)) {
(*best_denominator > max_denominator))
{
*best_numerator = 0;
*best_denominator = 0;
}
@@ -246,7 +263,8 @@ uint32_t hweight8(uint32_t word)
{
uint32_t count = 0;
while (word) {
while (word)
{
if (word & 0x1)
count++;
word >>= 1;
@@ -258,8 +276,8 @@ uint32_t hweight8(uint32_t word)
/**
* Calculate the quotient and the remainder of an integer division.
*/
uint64_t do_div(uint64_t* n,
uint64_t base)
uint64_t do_div(uint64_t *n,
uint64_t base)
{
uint64_t mod = 0;
@@ -348,4 +366,3 @@ uint32_t srt_to_uint32(const char *str)
else
return value;
}
+49 -46
View File
@@ -1,4 +1,4 @@
/***************************************************************************//**
/*******************************************************************************
* @file util.h
* @brief Implementation of utility functions.
* @author DBogdan (dragos.bogdan@analog.com)
@@ -48,19 +48,19 @@
/******************************************************************************/
/********************** Macros and Constants Definitions **********************/
/******************************************************************************/
//#define __CRC_LSB
// #define __CRC_LSB
#define __BITSWAP_TABLE
#define __CRC_LSB
#define CRC16_INIT 0x0000
#define CRC8_INIT 0x00
#define BIT(x) (1 << (x))
#define BIT(x) (1 << (x))
#define ARRAY_SIZE(x) \
(sizeof(x) / sizeof((x)[0]))
#define DIV_ROUND_UP(x,y) \
(((x) + (y) - 1) / (y))
#define DIV_ROUND_UP(x, y) \
(((x) + (y)-1) / (y))
#define DIV_ROUND_CLOSEST(x, y) \
(((x) + (y) / 2) / (y))
#define DIV_ROUND_CLOSEST_ULL(x, y) \
@@ -69,52 +69,56 @@
#define min(x, y) \
(((x) < (y)) ? (x) : (y))
#define min_t(type, x, y) \
(type)min((type)(x), (type)(y))
(type) min((type)(x), (type)(y))
#define max(x, y) \
(((x) > (y)) ? (x) : (y))
#define max_t(type, x, y) \
(type)max((type)(x), (type)(y))
(type) max((type)(x), (type)(y))
#define clamp(val, min_val, max_val) \
(max(min((val), (max_val)), (min_val)))
#define clamp_t(type, val, min_val, max_val) \
(type)clamp((type)(val), (type)(min_val), (type)(max_val))
(type) clamp((type)(val), (type)(min_val), (type)(max_val))
#define swap(x, y) \
{typeof(x) _tmp_ = (x); (x) = (y); (y) = _tmp_;}
#define swap(x, y) \
{ \
typeof(x) _tmp_ = (x); \
(x) = (y); \
(y) = _tmp_; \
}
#define round_up(x,y) \
(((x)+(y)-1)/(y))
#define round_up(x, y) \
(((x) + (y)-1) / (y))
#define BITS_PER_LONG 32
#define GENMASK(h, l) ({ \
uint32_t t = (uint32_t)(~0UL); \
t = t << (BITS_PER_LONG - (h - l + 1)); \
t = t >> (BITS_PER_LONG - (h + 1)); \
t; \
#define GENMASK(h, l) ({ \
uint32_t t = (uint32_t)(~0UL); \
t = t << (BITS_PER_LONG - (h - l + 1)); \
t = t >> (BITS_PER_LONG - (h + 1)); \
t; \
})
#define bswap_constant_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#define bswap_constant_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#define bswap_constant_16(x) ((((x) & (uint16_t)0xff00) >> 8) | \
(((x) & (uint16_t)0x00ff) << 8))
(((x) & (uint16_t)0x00ff) << 8))
#define bit_swap_constant_8(x) \
((((x) & 0x80) >> 7) | \
(((x) & 0x40) >> 5) | \
(((x) & 0x20) >> 3) | \
(((x) & 0x10) >> 1) | \
(((x) & 0x08) << 1) | \
(((x) & 0x04) << 3) | \
(((x) & 0x02) << 5) | \
((((x) & 0x80) >> 7) | \
(((x) & 0x40) >> 5) | \
(((x) & 0x20) >> 3) | \
(((x) & 0x10) >> 1) | \
(((x) & 0x08) << 1) | \
(((x) & 0x04) << 3) | \
(((x) & 0x02) << 5) | \
(((x) & 0x01) << 7))
#define U16_MAX ((uint16_t)~0U)
#define S16_MAX ((int16_t)(U16_MAX>>1))
#define U16_MAX ((uint16_t)~0U)
#define S16_MAX ((int16_t)(U16_MAX >> 1))
#define DIV_U64(x, y) (x / y)
@@ -147,8 +151,8 @@ uint32_t find_first_set_bit(uint32_t word);
uint32_t find_last_set_bit(uint32_t word);
/* Locate the closest element in an array. */
uint32_t find_closest(int32_t val,
const int32_t *array,
uint32_t size);
const int32_t *array,
uint32_t size);
/* Shift the value and apply the specified mask. */
uint32_t field_prep(uint32_t mask, uint32_t val);
/* Get a field specified by a mask from a word. */
@@ -157,22 +161,22 @@ uint32_t field_get(uint32_t mask, uint32_t word);
int32_t log_base_2(uint32_t x);
/* Find greatest common divisor of the given two numbers. */
uint32_t greatest_common_divisor(uint32_t a,
uint32_t b);
uint32_t b);
/* Calculate best rational approximation for a given fraction. */
void rational_best_approximation(uint32_t given_numerator,
uint32_t given_denominator,
uint32_t max_numerator,
uint32_t max_denominator,
uint32_t *best_numerator,
uint32_t *best_denominator);
uint32_t given_denominator,
uint32_t max_numerator,
uint32_t max_denominator,
uint32_t *best_numerator,
uint32_t *best_denominator);
/* Calculate the number of set bits. */
uint32_t hweight8(uint32_t word);
/* Calculate the quotient and the remainder of an integer division. */
uint64_t do_div(uint64_t* n,
uint64_t base);
uint64_t do_div(uint64_t *n,
uint64_t base);
/* Unsigned 64bit divide with 64bit divisor and remainder */
uint64_t div64_u64_rem(uint64_t dividend, uint64_t divisor,
uint64_t *remainder);
uint64_t *remainder);
/* Unsigned 64bit divide with 32bit divisor with remainder */
uint64_t div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder);
int64_t div_s64_rem(int64_t dividend, int32_t divisor, int32_t *remainder);
@@ -184,9 +188,8 @@ int32_t str_to_int32(const char *str);
/* Converts from string to uint32_t */
uint32_t srt_to_uint32(const char *str);
int crc16_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint16_t* crcVal);
bool crc16_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
int crc8_gen(uint8_t* buffPtr, uint32_t dataLen, uint16_t poly, uint8_t* crcVal);
bool crc8_check(uint8_t* buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
int crc16_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint16_t *crcVal);
bool crc16_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
int crc8_gen(uint8_t *buffPtr, uint32_t dataLen, uint16_t poly, uint8_t *crcVal);
bool crc8_check(uint8_t *buffPtr, uint32_t dataLen, uint32_t crcOffset, uint16_t poly);
#endif // __UTIL_H_
@@ -8,27 +8,31 @@
#include "linklayer/linklayer814.h"
#include "linklayer/msg_def.h"
#define TIME_INT_REG (0x00000008>>2)
#define TIME_FRAC_REG (0x0000000C>>2)
#define TIME_ADJ_INT (0x0000001C>>2)
#define TIME_ADJ_FRAC (0x00000020>>2)
#define TIME_ADJ_TRIG (0x00000024>>2)
#define CNTSTEP_OPT (0x00000028>>2)
#define TIME_INT_REG (0x00000008 >> 2)
#define TIME_FRAC_REG (0x0000000C >> 2)
#define TIME_ADJ_INT (0x0000001C >> 2)
#define TIME_ADJ_FRAC (0x00000020 >> 2)
#define TIME_ADJ_TRIG (0x00000024 >> 2)
#define CNTSTEP_OPT (0x00000028 >> 2)
TIMECTRL_INST* tmcInstPtr = NULL;
PHY_INST* phyInstPtr = NULL;
L2_INST* linkInstPtr = NULL;
TMC_INST *tmcInstPtr = NULL;
PHY_INST *phyInstPtr = NULL;
L2_INST *linkInstPtr = NULL;
uint32_t tmcReg[32] = {0};
uint32_t phycReg[512] = {0};
uint8_t bmTemplate[INTRA_BM_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) = {
uint8_t bmTemplate[INTRA_BM_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) =
{
0x08, 0x21, 0x04, 0x06, 0x00, 0xF3, 0xA8, 0xCB,
0x00, 0xA0, 0x49, 0x00, 0x9A, 0x04, 0x13, 0x1E,
0x45, 0xE7, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA
};
uint8_t w2acqTemplate[INTRA_W2ACQ_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) = {
uint8_t w2acqTemplate[INTRA_W2ACQ_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) =
{
0xCC, 0x71, 0x21, 0xA8, 0x0A, 0x00, 0x00, 0x00,
0x00, 0x1A, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00,
0xF0, 0xF0, 0x2A, 0x0F, 0x0F, 0xF0, 0x0F, 0x00,
@@ -62,7 +66,9 @@ uint8_t w2acqTemplate[INTRA_W2ACQ_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
};
uint8_t mgmtTemplate[INTRA_MGMT_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) = {
uint8_t mgmtTemplate[INTRA_MGMT_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) =
{
0xCC, 0xC3, 0x99, 0x99, 0x83, 0x99, 0x99, 0x99,
0x99, 0xA5, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xBA,
0xBB, 0x9B, 0x19, 0xCC, 0xCC, 0xDD, 0xDD, 0xEE,
@@ -96,7 +102,9 @@ uint8_t mgmtTemplate[INTRA_MGMT_FRAME_LENGTH_MAX] __attribute__ ((aligned (8)))
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t rttReqTemplate[INTRA_RTT_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) = {
uint8_t rttTemplate[INTRA_RTT_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) =
{
0xDC, 0xA3, 0x10, 0x44, 0x98, 0x99, 0x99, 0x99,
0x99, 0x05, 0x00, 0x00, 0x00, 0x50, 0x32, 0x01,
0x00, 0x90, 0x99, 0xFF, 0xFF, 0xFF, 0x99, 0x99,
@@ -130,47 +138,46 @@ uint8_t rttReqTemplate[INTRA_RTT_FRAME_LENGTH_MAX] __attribute__ ((aligned (8)))
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
uint8_t rttRspTemplate[INTRA_RTT_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) = {
0
};
uint8_t svcTemplate[INTRA_SVC_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) = {
0xF0, 0xFF, 0x00, 0x21, 0x88, 0x00, 0x00, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x56, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x21, 0xE6, 0x00, 0x21, 0x88, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
uint8_t svcTemplate[INTRA_SVC_FRAME_LENGTH_MAX] __attribute__ ((aligned (8))) =
{
0xF0, 0xFF, 0x00, 0x21, 0x88, 0x00, 0x00, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x56, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x21, 0xE6, 0x00, 0x21, 0x88, 0x00, 0x00,
0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xB5,
};
L2_CONFIG l2Config = {
.myType = HEAD_NODE,
L2_CONFIG l2Config =
{
.myType = L2_NODE_HEAD,
.isInterHead = false,
.myId = 1,
.clustId = 1,
@@ -181,7 +188,8 @@ L2_CONFIG l2Config = {
.tmcInstPtr = NULL
};
PHY_CONFIG l1Config = {
PHY_CONFIG l1Config =
{
.devId = 0,
.txBramId = 0,
.rxBramId = 0,
@@ -189,17 +197,21 @@ PHY_CONFIG l1Config = {
.baseAddr = (uintptr_t)phycReg
};
TIMECTRL_CONFIG tmcConfig = {
TMC_CONFIG tmcConfig =
{
.baseAddr = (uintptr_t)tmcReg,
.reset = 10
};
inline uint32_t rand_range(uint32_t a, uint32_t b){
int32_t rand_range(uint32_t a, uint32_t b);
inline int32_t rand_range(uint32_t a, uint32_t b)
{
ASSERT(b > a);
return (rand() % (b + 1 - a) + a);
}
void linklayer_setup(void){
void linklayer_setup(void)
{
int32_t Status;
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
ASSERT_EQUAL(SUCCESS, Status);
@@ -214,18 +226,20 @@ void linklayer_setup(void){
ASSERT_EQUAL(SUCCESS, Status);
}
void linklayer_teardown(void){
void linklayer_teardown(void)
{
Linklayer_Destroy(linkInstPtr);
Phy_Destroy(phyInstPtr);
TimeCtrl_Destroy(tmcInstPtr);
}
void forge_bm_frame(uint8_t* buff, uint8_t nodeId, uint16_t clustId, uint16_t headId, uint64_t time) {
void forge_bm_frame(uint8_t *buff, uint8_t nodeId, uint16_t clustId, uint16_t headId, uint64_t time)
{
BIT_ARRAY bitarr = {
.words = (uint64_t*)buff,
.num_of_bits = INTRA_BM_FRAME_LENGTH_MAX*8,
.num_of_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX*8),
.capacity_in_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX*8),
.words = (uint64_t *)buff,
.num_of_bits = INTRA_BM_FRAME_LENGTH_MAX * 8,
.num_of_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX * 8),
.capacity_in_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX * 8),
};
memcpy(buff, bmTemplate, INTRA_BM_FRAME_LENGTH_MAX);
uint64_t dataChunk;
@@ -252,19 +266,20 @@ void forge_bm_frame(uint8_t* buff, uint8_t nodeId, uint16_t clustId, uint16_t he
L2_CrcAppend(buff, BM_MSG_CRC_OFFSET / 8, BM_MSG_CRC_OFFSET / 8, L2_CRC8_31);
}
void forge_w2acq_frame(uint8_t* buff, L2_NODE_TYPE nodeType, uint16_t srcId, uint16_t destId,
uint16_t clustId, uint32_t netStartTime, L2_NODE_STATE state) {
void forge_w2acq_frame(uint8_t *buff, L2_NODE_TYPE nodeType, uint16_t srcId, uint16_t destId,
uint16_t clustId, uint32_t netStartTime, L2_NODE_STATE state)
{
BIT_ARRAY bitarr = {
.words = (uint64_t*)buff,
.num_of_bits = INTRA_W2ACQ_FRAME_LENGTH_MAX*8,
.num_of_words = roundup_bits2words64(INTRA_W2ACQ_FRAME_LENGTH_MAX*8),
.capacity_in_words = roundup_bits2words64(INTRA_W2ACQ_FRAME_LENGTH_MAX*8),
.words = (uint64_t *)buff,
.num_of_bits = INTRA_W2ACQ_FRAME_LENGTH_MAX * 8,
.num_of_words = roundup_bits2words64(INTRA_W2ACQ_FRAME_LENGTH_MAX * 8),
.capacity_in_words = roundup_bits2words64(INTRA_W2ACQ_FRAME_LENGTH_MAX * 8),
};
memcpy(buff, w2acqTemplate, INTRA_W2ACQ_FRAME_LENGTH_MAX);
uint64_t dataChunk;
/* message type */
dataChunk = (nodeType == HEAD_NODE) ? 0 : 1;
dataChunk = (nodeType == L2_NODE_HEAD) ? 0 : 1;
FrameInsertChunk(&bitarr, NS_MSG_INI_TYPE_OFFSET, NS_MSG_INI_TYPE_LEN, dataChunk);
/* source node id */
@@ -275,14 +290,15 @@ void forge_w2acq_frame(uint8_t* buff, L2_NODE_TYPE nodeType, uint16_t srcId, uin
dataChunk = (destId & 0x001F) | ((clustId & 0x001F) << 5);
FrameInsertChunk(&bitarr, NS_MSG_INI_LEN_OFFSET, NS_MSG_INI_LEN_LEN, dataChunk);
/* current net stage */
switch (state) {
case INIT_STATE:
switch (state)
{
case L2_INIT_STATE:
dataChunk = NET_INI_STAGE;
break;
case SEEK_STATE:
case L2_SEEK_STATE:
dataChunk = NET_INTER_SEEK_STAGE;
break;
case NORMAL_STATE:
case L2_NORMAL_STATE:
dataChunk = NET_NORMAL_STAGE;
break;
default:
@@ -299,80 +315,147 @@ void forge_w2acq_frame(uint8_t* buff, L2_NODE_TYPE nodeType, uint16_t srcId, uin
L2_CrcAppend(buff, W2ACQ_FRAME_CRC_DLEN, W2ACQ_FRAME_CRC_POS, L2_CRC16_8005);
}
void forge_mgmt_frame(uint8_t* buff, L2_NODE_STATE state) {
void forge_mgmt_frame(uint8_t *buff, L2_NODE_STATE state)
{
BIT_ARRAY bitarr = {
.words = (uint64_t*)buff,
.num_of_bits = INTRA_MGMT_FRAME_LENGTH_MAX*8,
.num_of_words = roundup_bits2words64(INTRA_MGMT_FRAME_LENGTH_MAX*8),
.capacity_in_words = roundup_bits2words64(INTRA_MGMT_FRAME_LENGTH_MAX*8),
.words = (uint64_t *)buff,
.num_of_bits = INTRA_MGMT_FRAME_LENGTH_MAX * 8,
.num_of_words = roundup_bits2words64(INTRA_MGMT_FRAME_LENGTH_MAX * 8),
.capacity_in_words = roundup_bits2words64(INTRA_MGMT_FRAME_LENGTH_MAX * 8),
};
memcpy(buff, mgmtTemplate, INTRA_MGMT_FRAME_LENGTH_MAX);
uint64_t dataChunk;
switch (state) {
case INIT_STATE:
switch (state)
{
case L2_INIT_STATE:
dataChunk = NET_INI_STAGE;
break;
case NORMAL_STATE:
case L2_NORMAL_STATE:
dataChunk = NET_NORMAL_STAGE;
break;
case INTRA_SEEK_STATE:
case L2_INTRA_SEEK_STATE:
dataChunk = NET_INTRA_SEEK_STAGE;
break;
case INTER_SEEK_STATE:
case L2_INTER_SEEK_STATE:
dataChunk = NET_INTER_SEEK_STAGE;
break;
case SEEK_STATE:
case L2_SEEK_STATE:
dataChunk = NET_SEEK_STAGE;
break;
default:
dataChunk = NET_ERROR_STAGE;
break;
FrameInsertChunk(&bitarr, TK_MSG_INI_NET_STATE_OFFSET, TK_MSG_INI_NET_STATE_LEN, dataChunk);
FrameInsertChunk(&bitarr, TK_MSG_INI_NET_STATE_OFFSET, TK_MSG_INI_NET_STATE_LEN, dataChunk);
}
}
void forge_rtt_frame(uint8_t* buff) {
// BIT_ARRAY bitarr = {
// .words = (uint64_t*)buff,
// .num_of_bits = INTRA_BM_FRAME_LENGTH_MAX*8,
// .num_of_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX*8),
// .capacity_in_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX*8),
// };
memcpy(buff, rttReqTemplate, INTRA_BM_FRAME_LENGTH_MAX);
void forge_rtt_frame(uint8_t *buff, uint16_t srcId, uint16_t destId,
uint16_t clustId, const TIME_WORD *timeStamp, uint32_t doppler)
{
BIT_ARRAY bitarr = {
.words = (uint64_t *)buff,
.num_of_bits = INTRA_BM_FRAME_LENGTH_MAX * 8,
.num_of_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX * 8),
.capacity_in_words = roundup_bits2words64(INTRA_BM_FRAME_LENGTH_MAX * 8),
};
memcpy(buff, rttTemplate, INTRA_BM_FRAME_LENGTH_MAX);
uint64_t dataChunk;
// INIT MSG
// --source node address.
dataChunk = (srcId & 0x001F) | ((clustId & 0x001F) << 5);
FrameInsertChunk(&bitarr, RTT_REQ_SRC_ADDR_OFFSET, RTT_REQ_SRC_ADDR_LEN, dataChunk);
// --destination node address.
dataChunk = (destId & 0x001F) | ((clustId & 0x001F) << 5);
FrameInsertChunk(&bitarr, RTT_REQ_DST_ADDR_OFFSET, RTT_REQ_DST_ADDR_LEN, dataChunk);
// EXTD MSG
// --Time tag Low
dataChunk = timeStamp->frac_part;
FrameInsertChunk(&bitarr, RTT_RSP_EX_TTAGL_OFFSET + RTT_MSG_LEN, RTT_RSP_EX_TTAGL_LEN, dataChunk);
// --Time tag High.
dataChunk = timeStamp->int_part;
FrameInsertChunk(&bitarr, RTT_RSP_EX_TTAGH_OFFSET + RTT_MSG_LEN, RTT_RSP_EX_TTAGH_LEN, dataChunk);
// CONT MSG
// -- Doppler
dataChunk = doppler;
FrameInsertChunk(&bitarr, RTT_RSP_CONT_DOP_OFFSET + RTT_MSG_LEN * 2, RTT_RSP_CONT_DOP_LEN, dataChunk);
return;
}
TEST(linklayer_master_routine) {
TEST(linklayer_reconfig)
{
int32_t Status;
Linklayer_Start(linkInstPtr);
Status = Linklayer_Reconfig(linkInstPtr, &l2Config);
ASSERT_EQUAL(SUCCESS, Status);
ASSERT_EQUAL(false, linkInstPtr->isEnable);
ASSERT_EQUAL(false, linkInstPtr->isEnable);
ASSERT_EQUAL(0, linkInstPtr->nodeList->len);
ASSERT_EQUAL(0, linkInstPtr->schdEventPool->envCnt);
}
TEST(linklayer_master_routine)
{
int32_t Status;
TIME_WORD timeStampA, timeStampB, timeGap;
uint32_t timeDiff;
l2Config.myType = L2_NODE_HEAD;
l2Config.myId = 1;
Status = Linklayer_Reconfig(linkInstPtr, &l2Config);
ASSERT_EQUAL(SUCCESS, Status);
// 30 seconds
for(int i = 0; i < 200*30; i++) {
Linklayer_Start(linkInstPtr);
for (int i = 0; i < 30 * L2_SLOTS_PER_FRAME; i++)
{
tmcReg[TIME_INT_REG]++;
if (L2_GetLastTor(linkInstPtr) == L2_TOR_RX && rand() < (RAND_MAX*0.8))
if (L2_GetNextTor(linkInstPtr) == L2_TOR_TX)
{
if(L2_GetLastFrameType(linkInstPtr) == L2_INTRA_W2_ACQ_FRAME) {
forge_w2acq_frame((uint8_t*)phyInstPtr->recvDataAddr, MEMBER_NODE, 2, 1, 1, -1, INIT_STATE);
if (L2_GetNextFrameType(linkInstPtr) == L2_INTRA_TSYNC_FRAME)
{
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStampA);
// ASSERT_EQUAL(linkInstPtr->rttFSM->rttRecord.Tt1.int_part + linkInstPtr->netStartTime*L2_SLOTS_PER_FRAME,
// timeStampA.int_part);
// ASSERT_EQUAL(linkInstPtr->rttFSM->rttRecord.Tt1.frac_part, timeStampA.frac_part);
timeStampA.frac_part = rand_range(0, 1000); // up to 10us deviation.
}
}
if (L2_GetCurrentTor(linkInstPtr) == L2_TOR_RX)
{
if (L2_GetCurrentFrameType(linkInstPtr) == L2_INTRA_W2_ACQ_FRAME)
{
forge_w2acq_frame((uint8_t *)phyInstPtr->recvDataAddr, L2_NODE_MEMBER, 2, 1, 1, -1, L2_INIT_STATE);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_W2ACQ_FRAME_LENGTH_MAX);
}
if (L2_GetLastFrameType(linkInstPtr) == L2_INTRA_MGMT_FRAME)
if (L2_GetCurrentFrameType(linkInstPtr) == L2_INTRA_MGMT_FRAME)
{
forge_mgmt_frame((uint8_t*)phyInstPtr->recvDataAddr, NORMAL_STATE);
forge_mgmt_frame((uint8_t *)phyInstPtr->recvDataAddr, L2_NORMAL_STATE);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_MGMT_FRAME_LENGTH_MAX);
}
if (L2_GetLastFrameType(linkInstPtr) == L2_INTRA_SVC_FRAME)
if (L2_GetCurrentFrameType(linkInstPtr) == L2_INTRA_TSYNC_FRAME)
{
forge_mgmt_frame((uint8_t*)phyInstPtr->recvDataAddr, NORMAL_STATE);
timeDiff = Phy_GetTimeComp(L2_L2frame2L1frame(L2_INTRA_TSYNC_FRAME)) + (rand() - RAND_MAX) % 1000;
TimeCtrl_CalculateTimeGap(&timeStampA, &timeStampB, &timeGap);
forge_rtt_frame((uint8_t *)phyInstPtr->recvDataAddr, 2, 1, 1, &timeGap, rand() % 200000);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, FSTIME_H, L2_GetLastFrameNum(linkInstPtr));
PhyWrite(phyInstPtr, FSTIME_L, timeDiff);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_MGMT_FRAME_LENGTH_MAX);
}
if (L2_GetCurrentFrameType(linkInstPtr) == L2_INTRA_SVC_FRAME)
{
forge_mgmt_frame((uint8_t *)phyInstPtr->recvDataAddr, L2_NORMAL_STATE);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_MGMT_FRAME_LENGTH_MAX);
}
}
else {
else
{
PhyWrite(phyInstPtr, TXRX_STATE, 0x02020202);
}
@@ -380,15 +463,19 @@ TEST(linklayer_master_routine) {
Status = Linklayer_Proc(linkInstPtr);
if((tmcReg[TIME_INT_REG]+1)/200 < linkInstPtr->netStartTime) {
if ((tmcReg[TIME_INT_REG] + 1) / 200 < linkInstPtr->netStartTime)
{
ASSERT_EQUAL(EIGNORE, Status);
}
else{
else
{
ASSERT_EQUAL(SUCCESS, Status);
}
if(L2_isDataAvail(linkInstPtr)) {
if(L2_GetLastFrameType(linkInstPtr) == L2_INTRA_W2_ACQ_FRAME) {
if (L2_isDataAvail(linkInstPtr))
{
if (L2_GetLastFrameType(linkInstPtr) == L2_INTRA_W2_ACQ_FRAME)
{
ASSERT_EQUAL(1, L2_GetNodeListLen(linkInstPtr->nodeList));
ASSERT_TRUE(L2_isNodeInList(linkInstPtr->nodeList, 2));
}
@@ -396,23 +483,126 @@ TEST(linklayer_master_routine) {
}
}
TEST(linklayer_reconfig) {
TEST(linklayer_slave_netsetup)
{
int32_t Status;
TIME_WORD timeStampA, timeStampB, timeGap;
TIME_WORD bmTime;
uint32_t netStart, timeDiff;
// 30 seconds
l2Config.myType = L2_NODE_MEMBER;
l2Config.myId = 2;
Status = Linklayer_Reconfig(linkInstPtr, &l2Config);
ASSERT_EQUAL(SUCCESS, Status);
tmcReg[TIME_FRAC_REG] = rand_range(0, TIME_FRAC_MAX);
tmcReg[TIME_INT_REG] = rand_range(0, 60 * L2_SLOTS_PER_FRAME); // 0~60s
bmTime.frac_part = rand_range(0, TIME_FRAC_MAX);
bmTime.int_part = rand_range(tmcReg[TIME_INT_REG], tmcReg[TIME_INT_REG] + 5 * L2_SLOTS_PER_FRAME);
// 74 is the index of bm frame in routine table.
netStart = bmTime.int_part % L2_SLOTS_PER_FRAME + rand_range(-12, 12);
Linklayer_Start(linkInstPtr);
for (int i = 0; i < 12 * L2_SLOTS_PER_FRAME * TIME_FRAC_MAX; i++)
{
tmcReg[TIME_FRAC_REG]++;
if (tmcReg[TIME_FRAC_REG] >= TIME_FRAC_MAX)
{
tmcReg[TIME_FRAC_REG] = 0;
tmcReg[TIME_INT_REG]++;
}
if (tmcReg[TIME_FRAC_REG] == bmTime.frac_part && tmcReg[TIME_INT_REG] == bmTime.int_part)
{
forge_bm_frame((uint8_t *)phyInstPtr->recvDataAddr, 1, 1, 1, netStart);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_BM_FRAME_LENGTH_MAX);
}
if (L2_GetNextTor(linkInstPtr) == L2_TOR_TX)
{
if (L2_GetNextFrameType(linkInstPtr) == L2_INTRA_TSYNC_FRAME)
{
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStampA);
timeStampA.frac_part = rand_range(0, 1000); // up to 10us deviation.
}
}
if (L2_GetCurrentTor(linkInstPtr) == L2_TOR_RX)
{
if (L2_GetCurrentFrameType(linkInstPtr) == L2_INTRA_W2_ACQ_FRAME)
{
forge_w2acq_frame((uint8_t *)phyInstPtr->recvDataAddr, L2_NODE_MEMBER, 2, 1, 1, -1, L2_INIT_STATE);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_W2ACQ_FRAME_LENGTH_MAX);
}
if (L2_GetCurrentFrameType(linkInstPtr) == L2_INTRA_MGMT_FRAME)
{
forge_mgmt_frame((uint8_t *)phyInstPtr->recvDataAddr, L2_NORMAL_STATE);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_MGMT_FRAME_LENGTH_MAX);
}
if (L2_GetCurrentFrameType(linkInstPtr) == L2_INTRA_TSYNC_FRAME)
{
timeDiff = Phy_GetTimeComp(L2_L2frame2L1frame(L2_INTRA_TSYNC_FRAME)) + (rand() - RAND_MAX) % 1000;
TimeCtrl_CalculateTimeGap(&timeStampA, &timeStampB, &timeGap);
forge_rtt_frame((uint8_t *)phyInstPtr->recvDataAddr, 2, 1, 1, &timeGap, rand() % 200000);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, FSTIME_H, L2_GetLastFrameNum(linkInstPtr));
PhyWrite(phyInstPtr, FSTIME_L, timeDiff);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_MGMT_FRAME_LENGTH_MAX);
}
if (L2_GetCurrentFrameType(linkInstPtr) == L2_INTRA_SVC_FRAME)
{
forge_mgmt_frame((uint8_t *)phyInstPtr->recvDataAddr, L2_NORMAL_STATE);
PhyWrite(phyInstPtr, TXRX_STATE, 0x01010101);
PhyWrite(phyInstPtr, RECVDATA_STATE, INTRA_MGMT_FRAME_LENGTH_MAX);
}
}
else
{
PhyWrite(phyInstPtr, TXRX_STATE, 0x02020202);
}
if (PhyRead(phyInstPtr, TXRX_STATE) != 0x02020202)
{
Phy_UpdateState(phyInstPtr);
}
if (tmcReg[TIME_FRAC_REG] == 200000)
{ // 2ms
Status = Linklayer_Proc(linkInstPtr);
if ((tmcReg[TIME_INT_REG] + 1) / 200 < linkInstPtr->netStartTime)
{
ASSERT_EQUAL(EIGNORE, Status);
}
else
{
ASSERT_EQUAL(SUCCESS, Status);
}
if (L2_isDataAvail(linkInstPtr))
{
if (L2_GetLastFrameType(linkInstPtr) == L2_INTRA_W2_ACQ_FRAME)
{
ASSERT_EQUAL(1, L2_GetNodeListLen(linkInstPtr->nodeList));
ASSERT_TRUE(L2_isNodeInList(linkInstPtr->nodeList, 2));
}
}
}
}
}
TEST_SUITE(linklayer_unit_test) {
TEST_SUITE(linklayer_unit_test)
{
TEST_SUITE_CONFIGURE(linklayer_setup, linklayer_teardown);
RUN_TEST(linklayer_master_routine);
RUN_TEST(linklayer_reconfig);
RUN_TEST(linklayer_master_routine);
RUN_TEST(linklayer_slave_netsetup);
}
int main(void) {
int main(void)
{
RUN_TEST_SUITE(linklayer_unit_test);
TEST_REPORT();
return TEST_EXIT_CODE;
}
+42 -33
View File
@@ -7,30 +7,32 @@
#define HARDWARE_VERSION 0x00000001
#define MAX_OPT_DELAY 100 // 1us = 100*10ns
TMC_CONFIG tmcConfig = {
.baseAddr = 0 /*TODO: fill withe real base address*/,
.reset = 10};
TIMECTRL_CONFIG tmcConfig = {
.baseAddr = 0/*TODO: fill withe real base address*/,
.reset = 10
};
TMC_INST *tmcInstPtr = NULL;
TIMECTRL_INST* tmcInstPtr = NULL;
void tmc_setup(void){
void tmc_setup(void)
{
int32_t Status;
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
ASSERT_TRUE(SUCCESS == Status);
}
void tmc_teardown(void){
void tmc_teardown(void)
{
TimeCtrl_Destroy(tmcInstPtr);
}
TEST(tmc_version) {
TEST(tmc_version)
{
ASSERT_EQUAL(HARDWARE_VERSION, TimeCtrl_GetVersion(tmcInstPtr));
return;
}
TEST(tmc_read_time) {
TEST(tmc_read_time)
{
TIME_WORD timeStamp;
TIME_INT timeH;
TIME_FRAC timeL;
@@ -39,17 +41,20 @@ TEST(tmc_read_time) {
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStamp);
timeH = TimeCtrl_GetIntCnt(tmcInstPtr);
timeL = TimeCtrl_GetFracCnt(tmcInstPtr);
if(timeL >= timeStamp.frac_part) {
if (timeL >= timeStamp.frac_part)
{
ASSERT_EQUAL(timeH, timeStamp.int_part);
ASSERT_TRUE(timeL - timeStamp.frac_part < MAX_OPT_DELAY);
}
else {
ASSERT_EQUAL(timeH, timeStamp.int_part+1);
ASSERT_TRUE(timeL + COUNTE_FRAC_MAX - timeStamp.frac_part < MAX_OPT_DELAY);
else
{
ASSERT_EQUAL(timeH, timeStamp.int_part + 1);
ASSERT_TRUE(timeL + TIME_FRAC_MAX - timeStamp.frac_part < MAX_OPT_DELAY);
}
}
TEST(tmc_reset) {
TEST(tmc_reset)
{
TIME_WORD timeStamp;
TimeCtrl_Reset(tmcInstPtr);
@@ -58,7 +63,8 @@ TEST(tmc_reset) {
ASSERT_TRUE(timeStamp.frac_part < MAX_OPT_DELAY);
}
TEST(tmc_adjustment) {
TEST(tmc_adjustment)
{
TIME_WORD timeStampPre, timeStampPost, timeAdj;
// Adjustment -- set
@@ -69,25 +75,27 @@ TEST(tmc_adjustment) {
ASSERT_EQUAL(timeAdj.int_part, timeStampPost.int_part);
ASSERT_TRUE(timeStampPost.frac_part < MAX_OPT_DELAY);
timeAdj.frac_part = COUNTE_FRAC_MAX;
timeAdj.frac_part = TIME_FRAC_MAX;
timeAdj.int_part = 0x00000203;
TimeCtrl_TimeAdjust(tmcInstPtr, &timeAdj, TM_ADJ_SET);
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStampPost);
ASSERT_EQUAL(timeAdj.int_part, timeStampPost.int_part+1);
ASSERT_EQUAL(timeAdj.int_part, timeStampPost.int_part + 1);
ASSERT_TRUE(timeStampPost.frac_part < MAX_OPT_DELAY);
timeAdj.frac_part = COUNTE_FRAC_MAX*2;
timeAdj.frac_part = TIME_FRAC_MAX * 2;
timeAdj.int_part = 0x00000203;
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStampPre);
TimeCtrl_TimeAdjust(tmcInstPtr, &timeAdj, TM_ADJ_SET);
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStampPost);
if(timeStampPost.frac_part >= timeStampPre.frac_part) {
if (timeStampPost.frac_part >= timeStampPre.frac_part)
{
ASSERT_EQUAL(timeStampPost.int_part, timeStampPre.int_part);
ASSERT_TRUE(timeStampPost.frac_part - timeStampPre.frac_part < MAX_OPT_DELAY);
}
else {
else
{
ASSERT_EQUAL(timeStampPost.int_part, timeStampPre.int_part + 1);
ASSERT_TRUE(timeStampPost.frac_part + COUNTE_FRAC_MAX - timeStampPre.frac_part < MAX_OPT_DELAY);
ASSERT_TRUE(timeStampPost.frac_part + TIME_FRAC_MAX - timeStampPre.frac_part < MAX_OPT_DELAY);
}
// Adjustment -- add
@@ -96,10 +104,10 @@ TEST(tmc_adjustment) {
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStampPre);
TimeCtrl_TimeAdjust(tmcInstPtr, &timeAdj, TM_ADJ_ADD);
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStampPost);
if(timeStampPre.frac_part + timeAdj.frac_part > COUNTE_FRAC_MAX) {
if (timeStampPre.frac_part + timeAdj.frac_part > TIME_FRAC_MAX)
{
ASSERT_TRUE(timeStampPost.int_part <= timeStampPre.int_part + timeAdj.int_part + 2);
ASSERT_TRUE(timeStampPost.frac_part + COUNTE_FRAC_MAX - timeStampPre.frac_part
< MAX_OPT_DELAY + timeAdj.frac_part);
ASSERT_TRUE(timeStampPost.frac_part + TIME_FRAC_MAX - timeStampPre.frac_part < MAX_OPT_DELAY + timeAdj.frac_part);
}
timeAdj.frac_part = -253;
@@ -107,19 +115,21 @@ TEST(tmc_adjustment) {
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStampPre);
TimeCtrl_TimeAdjust(tmcInstPtr, &timeAdj, TM_ADJ_ADD);
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStampPost);
if(timeStampPre.frac_part + timeAdj.frac_part > COUNTE_FRAC_MAX) {
if (timeStampPre.frac_part + timeAdj.frac_part > TIME_FRAC_MAX)
{
ASSERT_TRUE(timeStampPost.int_part <= timeStampPre.int_part + timeAdj.int_part + 2);
ASSERT_TRUE(timeStampPost.frac_part + COUNTE_FRAC_MAX - timeStampPre.frac_part
< MAX_OPT_DELAY + timeAdj.frac_part);
ASSERT_TRUE(timeStampPost.frac_part + TIME_FRAC_MAX - timeStampPre.frac_part < MAX_OPT_DELAY + timeAdj.frac_part);
}
}
TEST(tmc_setopt) {
TEST(tmc_setopt)
{
// TODO:
return;
}
TEST_SUITE(tmc_unit_test) {
TEST_SUITE(tmc_unit_test)
{
TEST_SUITE_CONFIGURE(tmc_setup, tmc_teardown);
RUN_TEST(tmc_version);
RUN_TEST(tmc_read_time);
@@ -128,10 +138,9 @@ TEST_SUITE(tmc_unit_test) {
RUN_TEST(tmc_setopt);
}
int main(void) {
int main(void)
{
RUN_TEST_SUITE(tmc_unit_test);
TEST_REPORT();
return TEST_EXIT_CODE;
}
@@ -11,53 +11,58 @@
uint32_t tmcReg[32] = {0};
TIMECTRL_CONFIG tmcConfig = {
TMC_CONFIG tmcConfig = {
.baseAddr = 0,
.reset = 10
};
.reset = 10};
TIMECTRL_INST* tmcInstPtr = NULL;
TMC_INST *tmcInstPtr = NULL;
void tmc_setup(void){
void tmc_setup(void)
{
int32_t Status;
tmcReg[1] = HARDWARE_VERSION; // Version
tmcReg[2] = 253; // Int
tmcReg[3] = 253; // Frac
tmcReg[4] = 0; // Reset
tmcReg[5] = 0; // Preset H
tmcReg[6] = 0; // Preset L
tmcReg[7] = 0; // Adjustment H
tmcReg[8] = 0; // Adjustment L
tmcReg[9] = 0; // Adjustment Trigger
tmcReg[10] = 0; // step opt
tmcReg[2] = 253; // Int
tmcReg[3] = 253; // Frac
tmcReg[4] = 0; // Reset
tmcReg[5] = 0; // Preset H
tmcReg[6] = 0; // Preset L
tmcReg[7] = 0; // Adjustment H
tmcReg[8] = 0; // Adjustment L
tmcReg[9] = 0; // Adjustment Trigger
tmcReg[10] = 0; // step opt
tmcConfig.baseAddr = (uintptr_t)tmcReg;
Status = TimeCtrl_Init(&tmcInstPtr, &tmcConfig);
ASSERT_EQUAL(SUCCESS, Status);
}
void tmc_teardown(void){
void tmc_teardown(void)
{
TimeCtrl_Destroy(tmcInstPtr);
}
TEST(tmc_version) {
TEST(tmc_version)
{
ASSERT_EQUAL(HARDWARE_VERSION, TimeCtrl_GetVersion(tmcInstPtr));
return;
}
TEST(tmc_basic_operations) {
TEST(tmc_basic_operations)
{
TIME_WORD timeStamp;
TIME_INT timeH;
TIME_FRAC timeL;
TimeCtrl_GetCurrentTime(tmcInstPtr, &timeStamp);
timeH = TimeCtrl_GetIntCnt(tmcInstPtr);
timeL = TimeCtrl_GetFracCnt(tmcInstPtr);
if(timeL >= timeStamp.frac_part) {
if (timeL >= timeStamp.frac_part)
{
ASSERT_EQUAL(timeH, timeStamp.int_part);
ASSERT_TRUE(timeL - timeStamp.frac_part < MAX_OPT_DELAY);
}
else {
ASSERT_EQUAL(timeH, timeStamp.int_part+1);
ASSERT_TRUE(timeL + COUNTE_FRAC_MAX - timeStamp.frac_part < MAX_OPT_DELAY);
else
{
ASSERT_EQUAL(timeH, timeStamp.int_part + 1);
ASSERT_TRUE(timeL + TIME_FRAC_MAX - timeStamp.frac_part < MAX_OPT_DELAY);
}
TIME_FRAC stepOpt;
@@ -69,16 +74,16 @@ TEST(tmc_basic_operations) {
return;
}
TEST_SUITE(tmc_unit_test) {
TEST_SUITE(tmc_unit_test)
{
TEST_SUITE_CONFIGURE(tmc_setup, tmc_teardown);
RUN_TEST(tmc_version);
RUN_TEST(tmc_basic_operations);
}
int main(void) {
int main(void)
{
RUN_TEST_SUITE(tmc_unit_test);
TEST_REPORT();
return TEST_EXIT_CODE;
}
+5 -9
View File
@@ -3,17 +3,13 @@
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/phy_ctrl/antenna.c \
../src/phy_ctrl/phy_ctrl.c
PHY_CTRL_SRC := $(wildcard ../src/phy_ctrl/*.c)
OBJS += \
./src/phy_ctrl/antenna.o \
./src/phy_ctrl/phy_ctrl.o
C_SRCS += $(PHY_CTRL_SRC)
C_DEPS += \
./src/phy_ctrl/antenna.d \
./src/phy_ctrl/phy_ctrl.d
OBJS += $(patsubst ../src/phy_ctrl/%.c, ./src/phy_ctrl/%.o, $(PHY_CTRL_SRC))
C_DEPS += $(patsubst ../src/phy_ctrl/%.c, ./src/phy_ctrl/%.d, $(PHY_CTRL_SRC))
# Each subdirectory must supply rules for building sources it contributes
+5 -6
View File
@@ -3,14 +3,13 @@
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/time_ctrl/time_ctrl.c
TIME_CTRL_SRC := $(wildcard ../src/time_ctrl/*.c)
OBJS += \
./src/time_ctrl/time_ctrl.o
C_SRCS += $(TIME_CTRL_SRC)
C_DEPS += \
./src/time_ctrl/time_ctrl.d
OBJS += $(patsubst ../src/time_ctrl/%.c, ./src/time_ctrl/%.o, $(TIME_CTRL_SRC))
C_DEPS += $(patsubst ../src/time_ctrl/%.c, ./src/time_ctrl/%.d, $(TIME_CTRL_SRC))
# Each subdirectory must supply rules for building sources it contributes
+98 -43
View File
@@ -1,18 +1,18 @@
/*****************************************************************************/
/**
* Description: Inter-Communication protocol implementation.
*
*
* Date: 2022-06-18 16:37
* LastEditTime: 2023-04-24 17:38
* Revisions: Rev 0.1
* History:
* History:
* [2022-06-18]: Initial version.
* [2023-04-24]: Bug fix:
* - Read frame type from PL status register.
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <stdint.h>
@@ -113,7 +113,7 @@ static int32_t EvalPhyConfig(INTER_COMM_INST* instPtr, uint8_t* msgPtr){
PHY_INST* phyRef = instPtr->phyInstPtr;
L1_FRAME_TYPE frameType = L1_NONE_FRAME;
PHY_TOR_TYPE torState = PHY_TOR_SUSPEND;
PHY_ANT_BEAM_WIDTH beamWidth = ANT_BEAM_NONE;
PHY_ANT_BEAM_WIDTH beamWidth = PHY_ANT_BEAM_NONE;
uint32_t beamNo = 0;
uint16_t msg_Recv = 0;
@@ -130,7 +130,7 @@ static int32_t EvalPhyConfig(INTER_COMM_INST* instPtr, uint8_t* msgPtr){
torState = PHY_TOR_RX;
}
else{
DBG_ERROR("[PHY Control] Tx/Rx state cannot be recognized...\n\r");
DBG_ERROR("[PHY Control] Tx/Rx state cannot be recognized...\n");
return EIGNORE;
}
instPtr->lastCtrlTimeTag = GetTimeWord(msgPtr+CTRL_TIME_OFFSET);
@@ -165,7 +165,7 @@ static int32_t EvalPhyConfig(INTER_COMM_INST* instPtr, uint8_t* msgPtr){
frameType = L1_40KBPS_20MS_FRAME;
break;
default:
DBG_ERROR("[PHY Control] Frame Type cannot be recognized...\n\r");
DBG_ERROR("[PHY Control] Frame Type cannot be recognized...\n");
return EIGNORE;
break;
}
@@ -187,8 +187,8 @@ static int32_t EvalPhyConfig(INTER_COMM_INST* instPtr, uint8_t* msgPtr){
phyRef->isPresetHop = false;
}
else{
DBG_ERROR("[PHY Control] Hopping Pattern Configure cannot be recognized...\n\r");
DBG_WARNING("[PHY Control] Using default preset hopping pattern instead...\n\r");
DBG_ERROR("[PHY Control] Hopping Pattern Configure cannot be recognized...\n");
DBG_WARNING("[PHY Control] Using default preset hopping pattern instead...\n");
return EIGNORE;
}
if(phyRef->isPresetHop == false){
@@ -199,17 +199,17 @@ static int32_t EvalPhyConfig(INTER_COMM_INST* instPtr, uint8_t* msgPtr){
}
}
if(msgPtr[INTER_MSG_CTRL_BEAM_MODE_OFFSET] == BEAM_MODE_WIDE){
beamWidth = ANT_BEAM_120;
beamWidth = PHY_ANT_BEAM_120;
}
else if(msgPtr[INTER_MSG_CTRL_BEAM_MODE_OFFSET] == BEAM_MODE_SUBNRW){
beamWidth = ANT_BEAM_25;
beamWidth = PHY_ANT_BEAM_25;
}
else if(msgPtr[INTER_MSG_CTRL_BEAM_MODE_OFFSET] == BEAM_MODE_NRW){
beamWidth = ANT_BEAM_8;
beamWidth = PHY_ANT_BEAM_16;
}
else{
DBG_ERROR("[PHY Control] Beam Width Configure cannot be recognized...\n\r");
DBG_WARNING("[PHY Control] Using default WILD beam (120 deg) instead...\n\r");
DBG_ERROR("[PHY Control] Beam Width Configure cannot be recognized...\n");
DBG_WARNING("[PHY Control] Using default WILD beam (120 deg) instead...\n");
return EIGNORE;
}
Status = Phy_SetBeamWidth(phyRef, beamWidth);
@@ -217,15 +217,15 @@ static int32_t EvalPhyConfig(INTER_COMM_INST* instPtr, uint8_t* msgPtr){
return Status;
}
beamNo = (uint32_t)msgPtr[INTER_MSG_CTRL_BEAM_NO_OFFSET];
if((beamNo<NUM_ANT_SUBNRRW_PATTERN && beamWidth == ANT_BEAM_25)
||(beamNo<NUM_ANT_NRRW_PATTERN && beamWidth == ANT_BEAM_8)
|| (beamNo == 0 && beamWidth == ANT_BEAM_120)){
Phy_SetBeamNo(phyRef, beamNo);
if((beamNo<L1_NUM_ANT_SUBNRRW_PATTERN && beamWidth == PHY_ANT_BEAM_25)
||(beamNo<L1_NUM_ANT_NRRW_PATTERN && beamWidth == PHY_ANT_BEAM_16)
|| (beamNo == 0 && beamWidth == PHY_ANT_BEAM_120)){
Phy_SetBeamNo(phyRef, beamNo, beamWidth);
}
else{
if(beamNo != 0x000000FF){
DBG_ERROR("[PHY Control] Beam Number Configure cannot be recognized...\n\r");
DBG_WARNING("[PHY Control] Using Beam Angle configure instead...\n\r");
DBG_ERROR("[PHY Control] Beam Number Configure cannot be recognized...\n");
DBG_WARNING("[PHY Control] Using Beam Angle configure instead...\n");
return EIGNORE;
}
// the angle config is a 16 bit fixed point data
@@ -242,10 +242,39 @@ static int32_t EvalPhyConfig(INTER_COMM_INST* instPtr, uint8_t* msgPtr){
}
}
// Power Mode and Attenuation control
if (msgPtr[INTER_MSG_CTRL_POWER_OFFSET] == CTRL_POWER_LOW)
{
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW);
}
else if (msgPtr[INTER_MSG_CTRL_POWER_OFFSET] == CTRL_POWER_FULL)
{
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL);
}
else
{
DBG_ERROR("[PHY Control] Unsupported power mode [0x%02X]\n",
msgPtr[INTER_MSG_CTRL_POWER_OFFSET]);
return FAILURE;
}
if(msgPtr[INTER_MSG_CTRL_RXATT_OFFSET] <= INTER_MSG_CTRL_RXATT_MAX
&& msgPtr[INTER_MSG_CTRL_TXATT_OFFSET] <= INTER_MSG_CTRL_TXATT_MAX)
{
Phy_AntConfigAttenuation(phyRef,
msgPtr[INTER_MSG_CTRL_RXATT_OFFSET],
msgPtr[INTER_MSG_CTRL_TXATT_OFFSET]
);
}
else
{
DBG_ERROR("[PHY Control] Attenuation exceeds max range.\n");
return FAILURE;
}
TIME_WORD tmWord = {0};
tmWord.int_part = (uint32_t)(instPtr->lastCtrlTimeTag >> 32);
tmWord.frac_part = (uint32_t)(instPtr->lastCtrlTimeTag);
Status = Phy_SetTimeWord(phyRef, &tmWord, TIME_WORD_POLL);
Status = Phy_SetTimeWord(phyRef, &tmWord, PHY_TIME_WORD_POLL);
Status = Phy_SetMode(phyRef, PHY_MODE_PULL);
Status = Phy_SetupNextSlot(phyRef, torState, frameType, instPtr->phySendBuff);
@@ -305,13 +334,13 @@ int32_t InterComm_Init(INTER_COMM_INST** instPtr, INTER_COMM_CONFIG* configPtr){
}
// Initial physical buffer
(*instPtr)->phyRecvBuff = calloc(TXRXDATA_MAX_LEN/sizeof(uint32_t), sizeof(uint32_t));
(*instPtr)->phyRecvBuff = calloc(L1_TXRXDATA_MAX_LEN/sizeof(uint32_t), sizeof(uint32_t));
if ((*instPtr)->phyRecvBuff == NULL) {
Status = EALLOC;
goto init_failed;
}
(*instPtr)->phySendBuff = calloc(TXRXDATA_MAX_LEN/sizeof(uint32_t), sizeof(uint32_t));
(*instPtr)->phySendBuff = calloc(L1_TXRXDATA_MAX_LEN/sizeof(uint32_t), sizeof(uint32_t));
if ((*instPtr)->phySendBuff == NULL) {
Status = EALLOC;
goto init_failed;
@@ -499,16 +528,42 @@ int32_t InterComm_MsgHandler(INTER_COMM_INST* instPtr){
break;
}
case INTER_MSG_MODESW_CODE:{
if(msgRecvPtr[MODESW_MODE_OFFSET] == MODESW_MODE_NORMAL){
if(msgRecvPtr[MODESW_MODE_OFFSET] == MODESW_MODE_NORMAL)
{
Phy_SetMode(instPtr->phyInstPtr, PHY_MODE_PULL);
}
else if(msgRecvPtr[MODESW_MODE_OFFSET] == MODESW_MODE_NETSET){
else if(msgRecvPtr[MODESW_MODE_OFFSET] == MODESW_MODE_NETSET)
{
PHY_INST* phyRef = instPtr->phyInstPtr;
// Power Mode and Attenuation control
if (msgRecvPtr[MODESW_POWER_OFFSET] == CTRL_POWER_LOW)
{
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW);
}
else if (msgRecvPtr[MODESW_POWER_OFFSET] == CTRL_POWER_FULL)
{
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL);
}
else
{
DBG_ERROR("[PHY Control] Unsupported power mode [0x%02X]\n",
msgRecvPtr[MODESW_POWER_OFFSET]);
break;
}
if(msgRecvPtr[MODESW_RXATT_OFFSET] <= MODESW_RXATT_MAX)
{
Phy_AntConfigAttenuation(phyRef, msgRecvPtr[MODESW_RXATT_OFFSET], MODESW_TXATT_SKIP);
}
else
{
DBG_ERROR("[PHY Control] Attenuation exceeds max range.\n");
}
uint64_t timeTemp;
TIME_WORD tmWord;
timeTemp = GetTimeWord(msgRecvPtr + MODESW_START_TIME_OFFSET);
tmWord.int_part = (uint32_t)(timeTemp>>32);;
tmWord.frac_part = (uint32_t)(timeTemp);
Status = Phy_SetTimeWord(instPtr->phyInstPtr, &tmWord, TIME_WORD_POLL);
Status = Phy_SetTimeWord(phyRef, &tmWord, PHY_TIME_WORD_POLL);
if(Status != SUCCESS){
return EPARAM;
}
@@ -516,7 +571,7 @@ int32_t InterComm_MsgHandler(INTER_COMM_INST* instPtr){
if(timeTemp == 0){
tmWord.frac_part = 0;
tmWord.int_part = 0;
Status = Phy_SetTimeWord(instPtr->phyInstPtr, &tmWord, TIME_WORD_LISTEN_TIMEOUT);
Status = Phy_SetTimeWord(phyRef, &tmWord, PHY_TIME_WORD_LISTEN_TIMEOUT);
if(Status != SUCCESS){
return EPARAM;
}
@@ -524,16 +579,16 @@ int32_t InterComm_MsgHandler(INTER_COMM_INST* instPtr){
else{
tmWord.frac_part += (uint32_t)(timeTemp);
tmWord.int_part += (uint32_t)(timeTemp>>32);
tmWord.int_part = (tmWord.frac_part >= TMWORD_FRAC_MAX) ? tmWord.int_part + 1:tmWord.int_part;
tmWord.frac_part %= TMWORD_FRAC_MAX;
Status = Phy_SetTimeWord(instPtr->phyInstPtr, &tmWord, TIME_WORD_LISTEN_TIMEOUT);
tmWord.int_part = (tmWord.frac_part >= TIME_FRAC_MAX) ? tmWord.int_part + 1:tmWord.int_part;
tmWord.frac_part %= TIME_FRAC_MAX;
Status = Phy_SetTimeWord(phyRef, &tmWord, PHY_TIME_WORD_LISTEN_TIMEOUT);
if(Status != SUCCESS){
return EPARAM;
}
}
instPtr->phyInstPtr->isPresetHop = true ;
Status = Phy_SetMode(instPtr->phyInstPtr, PHY_MODE_LISTEN);
Status = Phy_SetupNextSlot(instPtr->phyInstPtr, PHY_TOR_RX, L1_10KBPS_20MS_FRAME, NULL);
phyRef->isPresetHop = true ;
Status = Phy_SetMode(phyRef, PHY_MODE_LISTEN);
Status = Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_20MS_FRAME, NULL);
}
else{
return EPARAM;
@@ -702,18 +757,18 @@ int32_t InterComm_PhyDataUpload(INTER_COMM_INST* instPtr){
instPtr->lastPhyTimeTag = fsTimeL;
instPtr->lastPhyTimeTag |= ((uint64_t)fsTimeH)<<32;
uint32_t timeComp = Phy_GetTimeComp(lastFrameType);
if(timeComp == L1_FRAME_NONE_COMP){
if(timeComp == TIME_FRAC_MAX){
return FAILURE;
}
fsTimeH -= timeComp/TMWORD_FRAC_MAX;
timeComp %= TMWORD_FRAC_MAX;
fsTimeH -= timeComp/TIME_FRAC_MAX;
timeComp %= TIME_FRAC_MAX;
fsTimeH = (fsTimeL < timeComp)?(fsTimeH - 1):fsTimeH;
fsTimeL = (fsTimeL < timeComp)?(TMWORD_FRAC_MAX + fsTimeL - timeComp) : (fsTimeL - timeComp);
fsTimeL = (fsTimeL < timeComp)?(TIME_FRAC_MAX + fsTimeL - timeComp) : (fsTimeL - timeComp);
memcpy(txMsgBuff+DSEGRD_TIME_OFFSET, &fsTimeL, DSEGRD_TIME_LEN/2);
memcpy(txMsgBuff+DSEGRD_TIME_OFFSET + DSEGRD_TIME_LEN/2, &fsTimeH, DSEGRD_TIME_LEN/2);
// Doppler Estimate
double doppler = Phy_GetCoarseFreqEst(instPtr->phyInstPtr);
double doppler = Phy_GetFreqEst(instPtr->phyInstPtr);
// LSB = 0.001Hz
int64_t dopplerQnt = doppler*1000;
memcpy(txMsgBuff+DSEGRD_DPL_OFFSET, &dopplerQnt, DSEGRD_DPL_LEN);
@@ -787,13 +842,13 @@ int32_t InterComm_PhyDataUpload(INTER_COMM_INST* instPtr){
/*****************************************************************************/
/**
* @brief Append frame CRC-16 result to frame data buffer.
*
*
* @param buffPtr
* @param dataLen
*
*
* @return SUCCESS append successfully
* Other frame cannot be recognized.
*
*
******************************************************************************/
int AppendCrc(uint8_t* buffPtr, uint32_t dataLen) {
ASSERT(buffPtr != NULL);
@@ -822,13 +877,13 @@ int AppendCrc(uint8_t* buffPtr, uint32_t dataLen) {
/**
* @brief Check the frame CRC-16, witch can infer the frame should be dump
* or not.
*
*
* @param frameBuffPtr
* @param frameType
*
*
* @return true CRC check passed, good frame.
* false CRC check failed, bad frame.
*
*
******************************************************************************/
bool CrcCheck(uint8_t* buffPtr, uint32_t dataLen){
if (dataLen == 0) {
+24 -13
View File
@@ -1,19 +1,19 @@
/*****************************************************************************/
/**
* Description: Inter-Communication protocol, definitions and function
* Description: Inter-Communication protocol, definitions and function
* prototypes.
*
*
* Date: 2022-06-18 16:37
* LastEditTime: 2023-04-24 17:38
* Revisions: Rev 0.2
* History:
* History:
* [2022-06-18]: Initial version.
* [2023-04-24]: Bug fix:
* - Read frame type from PL status register.
*
*
* Copyright(c) 2022 Beijing Institute of Technology.
* Lab of Communication and Networking
*
*
******************************************************************************/
#ifndef INTER_COMM_H_
#define INTER_COMM_H_
@@ -65,7 +65,7 @@
#define WAKE_CMD_LPW_UP 0xCCCC
// mode swicth command
#define INTER_MSG_MODESW_LEN 0x0016 // 20byte + crc
#define INTER_MSG_MODESW_LEN 0x0018 // 22byte + crc
#define INTER_MSG_MODESW_CODE 0x0041
#define MODESW_START_TIME_OFFSET 0x0002
#define MODESW_START_TIME_LEN 0x0008
@@ -75,6 +75,14 @@
#define MODESW_MODE_LEN 0x0002
#define MODESW_MODE_NORMAL 0x0001
#define MODESW_MODE_NETSET 0x0002
#define MODESW_POWER_OFFSET 0x0014
#define MODESW_POWER_LEN 0x0001
#define MODESW_POWER_LOW 0xAA
#define MODESW_POWER_FULL 0xCC
#define MODESW_RXATT_OFFSET 0x0015
#define MODESW_RXATT_LEN 0x0001
#define MODESW_RXATT_MAX 0x1F
#define MODESW_TXATT_SKIP 0xFF
// physical layer control
#define INTER_MSG_CTRL_LEN 0x00BC // 186byte + 2byte crc
@@ -108,11 +116,10 @@
#define CTRL_TOR_TX 0xAA
#define CTRL_TOR_RX 0xCC
#define INTER_MSG_CTRL_SW_OFFSET 0x000D
#define INTER_MSG_CTRL_SW_LEN 0x0001
#define CTRL_SW_PW BIT(0)
#define CTRL_SW_TR BIT(1)
#define CTRL_SW_TOR BIT(2)
#define INTER_MSG_CTRL_POWER_OFFSET 0x000D
#define INTER_MSG_CTRL_POWER_LEN 0x0001
#define CTRL_POWER_LOW 0xAA
#define CTRL_POWER_FULL 0xCC
#define INTER_MSG_CTRL_HOP_MODE_OFFSET 0x000E
#define INTER_MSG_CTRL_HOP_MODE_LEN 0x0002
@@ -132,8 +139,12 @@
#define INTER_MSG_CTRL_BEAM_NO_OFFSET 0x00B3
#define INTER_MSG_CTRL_BEAM_NO_LEN 0x0001
#define INTER_MSG_CTRL_AMP_WT_OFFSET 0x00B4
#define INTER_MSG_CTRL_AMP_WT_LEN 0x0002
#define INTER_MSG_CTRL_RXATT_OFFSET 0x00B4
#define INTER_MSG_CTRL_RXATT_LEN 0x0001
#define INTER_MSG_CTRL_RXATT_MAX 0x1F
#define INTER_MSG_CTRL_TXATT_OFFSET 0x00B5
#define INTER_MSG_CTRL_TXATT_LEN 0x0001
#define INTER_MSG_CTRL_TXATT_MAX 0x1F
#define INTER_MSG_CTRL_OFFAX_OFFSET 0x00B6
#define INTER_MSG_CTRL_OFFAX_LEN 0x0002
+2 -2
View File
@@ -429,7 +429,7 @@ int32_t Intercom_C2cRecvData(void* buffPtr, int32_t buffSize){
return FAILURE;
}
}
uint32_t recvLen = IO_In32((uintptr_t)(c2cRecvDataPtr + C2C_DLEN_OFFSET)) - C2C_HEADER_LEN;
memcpy(buffPtr, c2cRecvDataPtr + C2C_PLOAD_OFFSET, recvLen);
@@ -747,7 +747,7 @@ int main(void) {
else{
Status = InterComm_MsgHandler(intrCommInstPtr);
if(Status != SUCCESS){
DBG_PRINT("####\tInterComm message handler finished with code: %d\n\r", Status);
DBG_PRINT("####\tInterComm message handler finished with code: %d\n", Status);
continue;
}
}
-35
View File
@@ -1,35 +0,0 @@
# Makefile generated by Xilinx.
PROCESSOR = ps7_cortexa9_0
LIBRARIES = ${PROCESSOR}/lib/libxil.a
BSP_MAKEFILES := $(wildcard $(PROCESSOR)/libsrc/*/src/Makefile)
SUBDIRS := $(patsubst %/Makefile, %, $(BSP_MAKEFILES))
ifneq (,$(findstring win,$(RDI_PLATFORM)))
SHELL = CMD
endif
all: libs
@echo 'Finished building libraries'
include: $(addsuffix /make.include,$(SUBDIRS))
libs: $(addsuffix /make.libs,$(SUBDIRS))
clean: $(addsuffix /make.clean,$(SUBDIRS))
$(PROCESSOR)/lib/libxil.a: $(PROCESSOR)/lib/libxil_init.a
cp -f $< $@
%/make.include: $(if $(wildcard $(PROCESSOR)/lib/libxil_init.a),$(PROCESSOR)/lib/libxil.a,)
@echo "Running Make include in $(subst /make.include,,$@)"
$(MAKE) -C $(subst /make.include,,$@) -s include "SHELL=$(SHELL)" "COMPILER=$(CC)" "ARCHIVER=arm-none-eabi-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-DDEBUG -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles -g -Wall -Wformat=2 -Wextra"
%/make.libs: include
@echo "Running Make libs in $(subst /make.libs,,$@)"
$(MAKE) -C $(subst /make.libs,,$@) -s libs "SHELL=$(SHELL)" "COMPILER=$(CC)" "ARCHIVER=arm-none-eabi-ar" "COMPILER_FLAGS= -O2 -c" "EXTRA_COMPILER_FLAGS=-DDEBUG -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard -nostartfiles -g -Wall -Wformat=2 -Wextra"
%/make.clean:
$(MAKE) -C $(subst /make.clean,,$@) -s clean
clean:
rm -f ${PROCESSOR}/lib/libxil.a
@@ -1,308 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2004 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************
*
* _program_timer_hw.h:
* Timer related functions
*
******************************************************************************/
#ifndef PROFILE_TIMER_HW_H
#define PROFILE_TIMER_HW_H
#include "profile.h"
#ifdef PROC_PPC
#if defined __GNUC__
# define SYNCHRONIZE_IO __asm__ volatile ("eieio")
#elif defined __DCC__
# define SYNCHRONIZE_IO __asm volatile(" eieio")
#else
# define SYNCHRONIZE_IO
#endif
#endif
#ifdef PROC_PPC
#define ProfIo_In32(InputPtr) { (*(volatile u32 *)(InputPtr)); SYNCHRONIZE_IO; }
#define ProfIo_Out32(OutputPtr, Value) { (*(volatile u32 *)(OutputPtr) = Value); SYNCHRONIZE_IO; }
#else
#define ProfIo_In32(InputPtr) (*(volatile u32 *)(InputPtr));
#define ProfIo_Out32(OutputPtr, Value) { (*(volatile u32 *)(OutputPtr) = (Value)); }
#endif
#define ProfTmrCtr_mWriteReg(BaseAddress, TmrCtrNumber, RegOffset, ValueToWrite)\
ProfIo_Out32(((u32)(BaseAddress) + (u32)XTmrCtr_Offsets[(TmrCtrNumber)] + \
(u32)(RegOffset)), (u32)(ValueToWrite))
#define ProfTimerCtr_mReadReg(BaseAddress, TmrCtrNumber, RegOffset) \
ProfIo_In32((u32)(BaseAddress) + (u32)XTmrCtr_Offsets[(TmrCtrNumber)] + (u32)(RegOffset))
#define ProfTmrCtr_mSetControlStatusReg(BaseAddress, TmrCtrNumber, RegisterValue)\
ProfTmrCtr_mWriteReg((BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET, \
(RegisterValue))
#define ProfTmrCtr_mGetControlStatusReg(BaseAddress, TmrCtrNumber) \
ProfTimerCtr_mReadReg((u32)(BaseAddress), (TmrCtrNumber), XTC_TCSR_OFFSET)
#ifdef __cplusplus
extern "C" {
#endif
#ifdef PROC_PPC
#include "xexception_l.h"
#include "xtime_l.h"
#include "xpseudo_asm.h"
#endif
#ifdef TIMER_CONNECT_INTC
#include "xintc_l.h"
#include "xintc.h"
#endif /* TIMER_CONNECT_INTC */
#if (!defined PPC_PIT_INTERRUPT && !defined PROC_CORTEXA9)
#include "xtmrctr_l.h"
#endif
#ifdef PROC_CORTEXA9
#include "xscutimer_hw.h"
#include "xscugic.h"
#endif
extern u32 timer_clk_ticks ;
/*--------------------------------------------------------------------
* PowerPC Target - Timer related functions
*-------------------------------------------------------------------- */
#ifdef PROC_PPC
#ifdef PPC_PIT_INTERRUPT
u32 timer_lo_clk_ticks ; /* Clk ticks when Timer is disabled in CG */
#endif
#ifdef PROC_PPC440
#define XREG_TCR_PIT_INTERRUPT_ENABLE XREG_TCR_DEC_INTERRUPT_ENABLE
#define XREG_TSR_PIT_INTERRUPT_STATUS XREG_TSR_DEC_INTERRUPT_STATUS
#define XREG_SPR_PIT XREG_SPR_DEC
#define XEXC_ID_PIT_INT XEXC_ID_DEC_INT
#endif
/* --------------------------------------------------------------------
* Disable the Timer - During Profiling
*
* For PIT Timer -
* 1. XTime_PITDisableInterrupt() ;
* 2. Store the remaining timer clk tick
* 3. Stop the PIT Timer
*-------------------------------------------------------------------- */
#ifdef PPC_PIT_INTERRUPT
#define disable_timer() \
{ \
u32 val; \
val=mfspr(XREG_SPR_TCR); \
mtspr(XREG_SPR_TCR, val & (~XREG_TCR_PIT_INTERRUPT_ENABLE)); \
timer_lo_clk_ticks = mfspr(XREG_SPR_PIT); \
mtspr(XREG_SPR_PIT, 0); \
}
#else
#define disable_timer() \
{ \
u32 addr = (PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET; \
u32 tmp_v = ProfIo_In32(addr); \
tmp_v = tmp_v & (~XTC_CSR_ENABLE_TMR_MASK); \
ProfIo_Out32((PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET, tmp_v); \
}
#endif
/* --------------------------------------------------------------------
* Enable the Timer
*
* For PIT Timer -
* 1. Load the remaining timer clk ticks
* 2. XTime_PITEnableInterrupt() ;
*-------------------------------------------------------------------- */
#ifdef PPC_PIT_INTERRUPT
#define enable_timer() \
{ \
u32 val; \
val=mfspr(XREG_SPR_TCR); \
mtspr(XREG_SPR_PIT, timer_lo_clk_ticks); \
mtspr(XREG_SPR_TCR, val | XREG_TCR_PIT_INTERRUPT_ENABLE); \
}
#else
#define enable_timer() \
{ \
u32 addr = (PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET; \
u32 tmp_v = ProfIo_In32(addr); \
tmp_v = tmp_v | XTC_CSR_ENABLE_TMR_MASK; \
ProfIo_Out32((PROFILE_TIMER_BASEADDR) + XTmrCtr_Offsets[(0)] + XTC_TCSR_OFFSET, tmp_v); \
}
#endif
/* --------------------------------------------------------------------
* Send Ack to Timer Interrupt
*
* For PIT Timer -
* 1. Load the timer clk ticks
* 2. Enable AutoReload and Interrupt
* 3. Clear PIT Timer Status bits
*-------------------------------------------------------------------- */
#ifdef PPC_PIT_INTERRUPT
#define timer_ack() \
{ \
u32 val; \
mtspr(XREG_SPR_PIT, timer_clk_ticks); \
mtspr(XREG_SPR_TSR, XREG_TSR_PIT_INTERRUPT_STATUS); \
val=mfspr(XREG_SPR_TCR); \
mtspr(XREG_SPR_TCR, val| XREG_TCR_PIT_INTERRUPT_ENABLE| XREG_TCR_AUTORELOAD_ENABLE); \
}
#else
#define timer_ack() \
{ \
u32 csr; \
csr = ProfTmrCtr_mGetControlStatusReg(PROFILE_TIMER_BASEADDR, 0); \
ProfTmrCtr_mSetControlStatusReg(PROFILE_TIMER_BASEADDR, 0, csr); \
}
#endif
/*-------------------------------------------------------------------- */
#endif /* PROC_PPC */
/* -------------------------------------------------------------------- */
/* --------------------------------------------------------------------
* MicroBlaze Target - Timer related functions
*-------------------------------------------------------------------- */
#ifdef PROC_MICROBLAZE
/* --------------------------------------------------------------------
* Disable the Timer during Call-Graph Data collection
*
*-------------------------------------------------------------------- */
#define disable_timer() \
{ \
u32 Addr = ((u32)PROFILE_TIMER_BASEADDR); \
Addr += (u32)XTmrCtr_Offsets[(u16)(0)]; \
Addr += (u32)XTC_TCSR_OFFSET; \
u32 tmp_v = ProfIo_In32(Addr); \
tmp_v = tmp_v & (u32)(~XTC_CSR_ENABLE_TMR_MASK); \
u32 OutAddr = (u32)PROFILE_TIMER_BASEADDR; \
OutAddr += (u32)XTmrCtr_Offsets[(u16)(0)]; \
OutAddr += (u32)XTC_TCSR_OFFSET; \
ProfIo_Out32(OutAddr, (u32)tmp_v); \
}
/* --------------------------------------------------------------------
* Enable the Timer after Call-Graph Data collection
*
*-------------------------------------------------------------------- */
#define enable_timer() \
{ \
u32 Addr = ((u32)PROFILE_TIMER_BASEADDR); \
Addr += (u32)XTmrCtr_Offsets[(u16)(0)]; \
Addr += (u32)XTC_TCSR_OFFSET; \
u32 tmp_v = (u32)ProfIo_In32(Addr); \
tmp_v = tmp_v | (u32)XTC_CSR_ENABLE_TMR_MASK; \
ProfIo_Out32((u32)(PROFILE_TIMER_BASEADDR) + (u32)XTmrCtr_Offsets[(u16)(0)] + (u32)XTC_TCSR_OFFSET, (u32)tmp_v); \
}
/* --------------------------------------------------------------------
* Send Ack to Timer Interrupt
*
*-------------------------------------------------------------------- */
#define timer_ack() \
{ \
u32 csr; \
csr = ProfTmrCtr_mGetControlStatusReg((u32)PROFILE_TIMER_BASEADDR, (u16)0); \
ProfTmrCtr_mSetControlStatusReg((u32)PROFILE_TIMER_BASEADDR, (u16)0, (u32)csr); \
}
/*-------------------------------------------------------------------- */
#endif /* PROC_MICROBLAZE */
/*-------------------------------------------------------------------- */
/* --------------------------------------------------------------------
* Cortex A9 Target - Timer related functions
*-------------------------------------------------------------------- */
#ifdef PROC_CORTEXA9
/* --------------------------------------------------------------------
* Disable the Timer during Call-Graph Data collection
*
*-------------------------------------------------------------------- */
#define disable_timer() \
{ \
u32 Reg; \
Reg = Xil_In32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET); \
Reg &= (~XSCUTIMER_CONTROL_ENABLE_MASK);\
Xil_Out32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET, Reg);\
}
/* --------------------------------------------------------------------
* Enable the Timer after Call-Graph Data collection
*
*-------------------------------------------------------------------- */
#define enable_timer() \
{ \
u32 Reg; \
Reg = Xil_In32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET); \
Reg |= XSCUTIMER_CONTROL_ENABLE_MASK; \
Xil_Out32(PROFILE_TIMER_BASEADDR + XSCUTIMER_CONTROL_OFFSET, Reg);\
}
/* --------------------------------------------------------------------
* Send Ack to Timer Interrupt
*
*-------------------------------------------------------------------- */
#define timer_ack() \
{ \
Xil_Out32((u32)PROFILE_TIMER_BASEADDR + (u32)XSCUTIMER_ISR_OFFSET, \
(u32)XSCUTIMER_ISR_EVENT_FLAG_MASK);\
}
/*-------------------------------------------------------------------- */
#endif /* PROC_CORTEXA9 */
/*-------------------------------------------------------------------- */
#ifdef __cplusplus
}
#endif
#endif
@@ -1,44 +0,0 @@
/*******************************************************************
*
* CAUTION: This file is automatically generated by HSI.
* Version: 2019.1.3
* DO NOT EDIT.
*
* Copyright (C) 2010-2023 Xilinx, Inc. All Rights Reserved.*
*Permission is hereby granted, free of charge, to any person obtaining a copy
*of this software and associated documentation files (the Software), to deal
*in the Software without restriction, including without limitation the rights
*to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*copies of the Software, and to permit persons to whom the Software is
*furnished to do so, subject to the following conditions:
*
*The above copyright notice and this permission notice shall be included in
*all copies or substantial portions of the Software.
*
*THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
*XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
*WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
*OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*Except as contained in this notice, the name of the Xilinx shall not be used
*in advertising or otherwise to promote the sale, use or other dealings in
*this Software without prior written authorization from Xilinx.
*
*
* Description: Configurations for Standalone BSP
*
*******************************************************************/
#ifndef BSPCONFIG_H /* prevent circular inclusions */
#define BSPCONFIG_H /* by using protection macros */
#define MICROBLAZE_PVR_NONE
/* Definition for hard-float ABI */
#define FPU_HARD_FLOAT_ABI_ENABLED 1
#endif /*end of __BSPCONFIG_H_*/
@@ -1,50 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#ifndef _MBLAZE_NT_TYPES_H
#define _MBLAZE_NT_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
typedef char byte;
typedef short half;
typedef int word;
typedef unsigned char ubyte;
typedef unsigned short uhalf;
typedef unsigned int uword;
typedef ubyte boolean;
#ifdef __cplusplus
}
#endif
#endif
@@ -1,127 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#ifndef PROFILE_H
#define PROFILE_H 1
#include <stdio.h>
#include "xil_types.h"
#include "profile_config.h"
#ifdef PROC_MICROBLAZE
#include "mblaze_nt_types.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
void _system_init( void ) ;
void _system_clean( void ) ;
void mcount(u32 frompc, u32 selfpc);
void profile_intr_handler( void ) ;
void _profile_init( void );
/****************************************************************************
* Profiling on hardware - Hash table maintained on hardware and data sent
* to xmd for gmon.out generation.
****************************************************************************/
/*
* histogram counters are unsigned shorts (according to the kernel).
*/
#define HISTCOUNTER u16
struct tostruct {
u32 selfpc;
s32 count;
s16 link;
u16 pad;
};
struct fromstruct {
u32 frompc ;
s16 link ;
u16 pad ;
} ;
/*
* general rounding functions.
*/
#define ROUNDDOWN(x,y) (((x)/(y))*(y))
#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
/*
* The profiling data structures are housed in this structure.
*/
struct gmonparam {
s32 state;
/* Histogram Information */
u16 *kcount; /* No. of bins in histogram */
u32 kcountsize; /* Histogram samples */
/* Call-graph Information */
struct fromstruct *froms;
u32 fromssize;
struct tostruct *tos;
u32 tossize;
/* Initialization I/Ps */
u32 lowpc;
u32 highpc;
u32 textsize;
/* u32 cg_froms, */
/* u32 cg_tos, */
};
extern struct gmonparam *_gmonparam;
extern s32 n_gmon_sections;
/*
* Possible states of profiling.
*/
#define GMON_PROF_ON 0
#define GMON_PROF_BUSY 1
#define GMON_PROF_ERROR 2
#define GMON_PROF_OFF 3
/*
* Sysctl definitions for extracting profiling information from the kernel.
*/
#define GPROF_STATE 0 /* int: profiling enabling variable */
#define GPROF_COUNT 1 /* struct: profile tick count buffer */
#define GPROF_FROMS 2 /* struct: from location hash bucket */
#define GPROF_TOS 3 /* struct: destination/count structure */
#define GPROF_GMONPARAM 4 /* struct: profiling parameters (see above) */
#ifdef __cplusplus
}
#endif
#endif /* PROFILE_H */
@@ -1,115 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2014 - 2017 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file sleep.h
*
* This header file contains ARM Cortex A53,A9,R5,Microblaze specific sleep
* related APIs.
*
* <pre>
* MODIFICATION HISTORY :
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 6.6 srm 11/02/17 Added processor specific sleep rountines
* function prototypes.
*
* </pre>
*
******************************************************************************/
#ifndef SLEEP_H
#define SLEEP_H
#include "xil_types.h"
#include "xil_io.h"
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************/
/**
*
* This macro polls an address periodically until a condition is met or till the
* timeout occurs.
* The minimum timeout for calling this macro is 100us. If the timeout is less
* than 100us, it still waits for 100us. Also the unit for the timeout is 100us.
* If the timeout is not a multiple of 100us, it waits for a timeout of
* the next usec value which is a multiple of 100us.
*
* @param IO_func - accessor function to read the register contents.
* Depends on the register width.
* @param ADDR - Address to be polled
* @param VALUE - variable to read the value
* @param COND - Condition to checked (usually involves VALUE)
* @param TIMEOUT_US - timeout in micro seconds
*
* @return 0 - when the condition is met
* -1 - when the condition is not met till the timeout period
*
* @note none
*
*****************************************************************************/
#define Xil_poll_timeout(IO_func, ADDR, VALUE, COND, TIMEOUT_US) \
( { \
u64 timeout = TIMEOUT_US/100; \
if(TIMEOUT_US%100!=0) \
timeout++; \
for(;;) { \
VALUE = IO_func(ADDR); \
if(COND) \
break; \
else { \
usleep(100); \
timeout--; \
if(timeout==0) \
break; \
} \
} \
(timeout>0) ? 0 : -1; \
} )
void usleep(unsigned long useconds);
void sleep(unsigned int seconds);
int usleep_R5(unsigned long useconds);
unsigned sleep_R5(unsigned int seconds);
int usleep_MB(unsigned long useconds);
unsigned sleep_MB(unsigned int seconds);
int usleep_A53(unsigned long useconds);
unsigned sleep_A53(unsigned int seconds);
int usleep_A9(unsigned long useconds);
unsigned sleep_A9(unsigned int seconds);
#ifdef __cplusplus
}
#endif
#endif
@@ -1,110 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file smc.h
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------
* 1.00a sdm 11/03/09 Initial release.
* 4.2 pkp 08/04/14 Removed function definition of XSmc_NorInit and XSmc_NorInit
* as smc.c is removed
* </pre>
*
* @note None.
*
******************************************************************************/
#ifndef SMC_H /* prevent circular inclusions */
#define SMC_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xparameters.h"
#include "xil_io.h"
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Constant Definitions *****************************/
/* Memory controller configuration register offset */
#define XSMCPSS_MC_STATUS 0x000U /* Controller status reg, RO */
#define XSMCPSS_MC_INTERFACE_CONFIG 0x004U /* Interface config reg, RO */
#define XSMCPSS_MC_SET_CONFIG 0x008U /* Set configuration reg, WO */
#define XSMCPSS_MC_CLR_CONFIG 0x00CU /* Clear config reg, WO */
#define XSMCPSS_MC_DIRECT_CMD 0x010U /* Direct command reg, WO */
#define XSMCPSS_MC_SET_CYCLES 0x014U /* Set cycles register, WO */
#define XSMCPSS_MC_SET_OPMODE 0x018U /* Set opmode register, WO */
#define XSMCPSS_MC_REFRESH_PERIOD_0 0x020U /* Refresh period_0 reg, RW */
#define XSMCPSS_MC_REFRESH_PERIOD_1 0x024U /* Refresh period_1 reg, RW */
/* Chip select configuration register offset */
#define XSMCPSS_CS_IF0_CHIP_0_OFFSET 0x100U /* Interface 0 chip 0 config */
#define XSMCPSS_CS_IF0_CHIP_1_OFFSET 0x120U /* Interface 0 chip 1 config */
#define XSMCPSS_CS_IF0_CHIP_2_OFFSET 0x140U /* Interface 0 chip 2 config */
#define XSMCPSS_CS_IF0_CHIP_3_OFFSET 0x160U /* Interface 0 chip 3 config */
#define XSMCPSS_CS_IF1_CHIP_0_OFFSET 0x180U /* Interface 1 chip 0 config */
#define XSMCPSS_CS_IF1_CHIP_1_OFFSET 0x1A0U /* Interface 1 chip 1 config */
#define XSMCPSS_CS_IF1_CHIP_2_OFFSET 0x1C0U /* Interface 1 chip 2 config */
#define XSMCPSS_CS_IF1_CHIP_3_OFFSET 0x1E0U /* Interface 1 chip 3 config */
/* User configuration register offset */
#define XSMCPSS_UC_STATUS_OFFSET 0x200U /* User status reg, RO */
#define XSMCPSS_UC_CONFIG_OFFSET 0x204U /* User config reg, WO */
/* Integration test register offset */
#define XSMCPSS_IT_OFFSET 0xE00U
/* ID configuration register offset */
#define XSMCPSS_ID_PERIP_0_OFFSET 0xFE0U
#define XSMCPSS_ID_PERIP_1_OFFSET 0xFE4U
#define XSMCPSS_ID_PERIP_2_OFFSET 0xFE8U
#define XSMCPSS_ID_PERIP_3_OFFSET 0xFECU
#define XSMCPSS_ID_PCELL_0_OFFSET 0xFF0U
#define XSMCPSS_ID_PCELL_1_OFFSET 0xFF4U
#define XSMCPSS_ID_PCELL_2_OFFSET 0xFF8U
#define XSMCPSS_ID_PCELL_3_OFFSET 0xFFCU
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* SMC_H */
@@ -1,84 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2016 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file vectors.h
*
* This file contains the C level vector prototypes for the ARM Cortex A9 core.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------
* 1.00a ecm 10/20/10 Initial version, moved over from bsp area
* 6.0 mus 07/27/16 Consolidated vectors for a9,a53 and r5 processors
* </pre>
*
* @note
*
* None.
*
******************************************************************************/
#ifndef _VECTORS_H_
#define _VECTORS_H_
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Constant Definitions *****************************/
/************************** Function Prototypes ******************************/
void FIQInterrupt(void);
void IRQInterrupt(void);
#if !defined (__aarch64__)
void SWInterrupt(void);
void DataAbortInterrupt(void);
void PrefetchAbortInterrupt(void);
void UndefinedException(void);
#else
void SynchronousInterrupt(void);
void SErrorInterrupt(void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* protection macro */
@@ -1,589 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xadcps.h
* @addtogroup xadcps_v2_3
* @{
* @details
*
* The XAdcPs driver supports the Xilinx XADC/ADC device.
*
* The XADC/ADC device has the following features:
* - 10-bit, 200-KSPS (kilo samples per second)
* Analog-to-Digital Converter (ADC)
* - Monitoring of on-chip supply voltages and temperature
* - 1 dedicated differential analog-input pair and
* 16 auxiliary differential analog-input pairs
* - Automatic alarms based on user defined limits for the on-chip
* supply voltages and temperature
* - Automatic Channel Sequencer, programmable averaging, programmable
* acquisition time for the external inputs, unipolar or differential
* input selection for the external inputs
* - Inbuilt Calibration
* - Optional interrupt request generation
*
*
* The user should refer to the hardware device specification for detailed
* information about the device.
*
* This header file contains the prototypes of driver functions that can
* be used to access the XADC/ADC device.
*
*
* <b> XADC Channel Sequencer Modes </b>
*
* The XADC Channel Sequencer supports the following operating modes:
*
* - <b> Default </b>: This is the default mode after power up.
* In this mode of operation the XADC operates in
* a sequence mode, monitoring the on chip sensors:
* Temperature, VCCINT, and VCCAUX.
* - <b> One pass through sequence </b>: In this mode the XADC
* converts the channels enabled in the Sequencer Channel Enable
* registers for a single pass and then stops.
* - <b> Continuous cycling of sequence </b>: In this mode the XADC
* converts the channels enabled in the Sequencer Channel Enable
* registers continuously.
* - <b> Single channel mode</b>: In this mode the XADC Channel
* Sequencer is disabled and the XADC operates in a
* Single Channel Mode.
* The XADC can operate either in a Continuous or Event
* driven sampling mode in the single channel mode.
* - <b> Simultaneous Sampling Mode</b>: In this mode the XADC Channel
* Sequencer will automatically sequence through eight fixed pairs
* of auxiliary analog input channels for simulataneous conversion.
* - <b> Independent ADC mode</b>: In this mode the first ADC (A) is used to
* is used to implement a fixed monitoring mode similar to the
* default mode but the alarm fucntions ar eenabled.
* The second ADC (B) is available to be used with external analog
* input channels only.
*
* Read the XADC spec for more information about the sequencer modes.
*
* <b> Initialization and Configuration </b>
*
* The device driver enables higher layer software (e.g., an application) to
* communicate to the XADC/ADC device.
*
* XAdcPs_CfgInitialize() API is used to initialize the XADC/ADC
* device. The user needs to first call the XAdcPs_LookupConfig() API which
* returns the Configuration structure pointer which is passed as a parameter to
* the XAdcPs_CfgInitialize() API.
*
*
* <b>Interrupts</b>
*
* The XADC/ADC device supports interrupt driven mode and the default
* operation mode is polling mode.
*
* The interrupt mode is available only if hardware is configured to support
* interrupts.
*
* This driver does not provide a Interrupt Service Routine (ISR) for the device.
* It is the responsibility of the application to provide one if needed. Refer to
* the interrupt example provided with this driver for details on using the
* device in interrupt mode.
*
*
* <b> Virtual Memory </b>
*
* This driver supports Virtual Memory. The RTOS is responsible for calculating
* the correct device base address in Virtual Memory space.
*
*
* <b> Threads </b>
*
* This driver is not thread safe. Any needs for threads or thread mutual
* exclusion must be satisfied by the layer above this driver.
*
*
* <b> Asserts </b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on argument
* values. Asserts can be turned off on a system-wide basis by defining, at
* compile time, the NDEBUG identifier. By default, asserts are turned on and it
* is recommended that users leave asserts on during development.
*
*
* <b> Building the driver </b>
*
* The XAdcPs driver is composed of several source files. This allows the user
* to build and link only those parts of the driver that are necessary.
*
* <b> Limitations of the driver </b>
*
* XADC/ADC device can be accessed through the JTAG port and the PLB
* interface. The driver implementation does not support the simultaneous access
* of the device by both these interfaces. The user has to care of this situation
* in the user application code.
*
* <br><br>
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------------
* 1.00a ssb 12/22/11 First release based on the XPS/AXI xadc driver
* 1.01a bss 02/18/13 Modified XAdcPs_SetSeqChEnables,XAdcPs_SetSeqAvgEnables
* XAdcPs_SetSeqInputMode and XAdcPs_SetSeqAcqTime APIs
* in xadcps.c to fix CR #693371
* 1.03a bss 11/01/13 Modified xadcps_hw.h to use correct Register offsets
* CR#749687
* 2.1 bss 08/05/14 Added declarations for XAdcPs_SetSequencerEvent,
* XAdcPs_GetSamplingMode, XAdcPs_SetMuxMode,
* XAdcPs_SetPowerdownMode and XAdcPs_GetPowerdownMode
* functions.
* Modified Assert for XAdcPs_SetSingleChParams in
* xadcps.c to fix CR #807563.
* 2.2 bss 04/27/14 Modified to use correct Device Config base address in
* xadcps.c (CR#854437).
* ms 01/23/17 Added xil_printf statement in main function for all
* examples to ensure that "Successfully ran" and "Failed"
* strings are available in all examples. This is a fix
* for CR-965028.
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
* generation.
* ms 04/05/17 Modified Comment lines in functions of xadcps
* examples to recognize it as documentation block
* for doxygen generation.
* 2.3 mn 07/09/18 Fix Doxygen warning
*
* </pre>
*
*****************************************************************************/
#ifndef XADCPS_H /* Prevent circular inclusions */
#define XADCPS_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xadcps_hw.h"
/************************** Constant Definitions ****************************/
/**
* @name Indexes for the different channels.
* @{
*/
#define XADCPS_CH_TEMP 0x0 /**< On Chip Temperature */
#define XADCPS_CH_VCCINT 0x1 /**< VCCINT */
#define XADCPS_CH_VCCAUX 0x2 /**< VCCAUX */
#define XADCPS_CH_VPVN 0x3 /**< VP/VN Dedicated analog inputs */
#define XADCPS_CH_VREFP 0x4 /**< VREFP */
#define XADCPS_CH_VREFN 0x5 /**< VREFN */
#define XADCPS_CH_VBRAM 0x6 /**< On-chip VBRAM Data Reg, 7 series */
#define XADCPS_CH_SUPPLY_CALIB 0x07 /**< Supply Calib Data Reg */
#define XADCPS_CH_ADC_CALIB 0x08 /**< ADC Offset Channel Reg */
#define XADCPS_CH_GAINERR_CALIB 0x09 /**< Gain Error Channel Reg */
#define XADCPS_CH_VCCPINT 0x0D /**< On-chip PS VCCPINT Channel , Zynq */
#define XADCPS_CH_VCCPAUX 0x0E /**< On-chip PS VCCPAUX Channel , Zynq */
#define XADCPS_CH_VCCPDRO 0x0F /**< On-chip PS VCCPDRO Channel , Zynq */
#define XADCPS_CH_AUX_MIN 16 /**< Channel number for 1st Aux Channel */
#define XADCPS_CH_AUX_MAX 31 /**< Channel number for Last Aux channel */
/*@}*/
/**
* @name Indexes for reading the Calibration Coefficient Data.
* @{
*/
#define XADCPS_CALIB_SUPPLY_COEFF 0 /**< Supply Offset Calib Coefficient */
#define XADCPS_CALIB_ADC_COEFF 1 /**< ADC Offset Calib Coefficient */
#define XADCPS_CALIB_GAIN_ERROR_COEFF 2 /**< Gain Error Calib Coefficient*/
/*@}*/
/**
* @name Indexes for reading the Minimum/Maximum Measurement Data.
* @{
*/
#define XADCPS_MAX_TEMP 0 /**< Maximum Temperature Data */
#define XADCPS_MAX_VCCINT 1 /**< Maximum VCCINT Data */
#define XADCPS_MAX_VCCAUX 2 /**< Maximum VCCAUX Data */
#define XADCPS_MAX_VBRAM 3 /**< Maximum VBRAM Data */
#define XADCPS_MIN_TEMP 4 /**< Minimum Temperature Data */
#define XADCPS_MIN_VCCINT 5 /**< Minimum VCCINT Data */
#define XADCPS_MIN_VCCAUX 6 /**< Minimum VCCAUX Data */
#define XADCPS_MIN_VBRAM 7 /**< Minimum VBRAM Data */
#define XADCPS_MAX_VCCPINT 8 /**< Maximum VCCPINT Register , Zynq */
#define XADCPS_MAX_VCCPAUX 9 /**< Maximum VCCPAUX Register , Zynq */
#define XADCPS_MAX_VCCPDRO 0xA /**< Maximum VCCPDRO Register , Zynq */
#define XADCPS_MIN_VCCPINT 0xC /**< Minimum VCCPINT Register , Zynq */
#define XADCPS_MIN_VCCPAUX 0xD /**< Minimum VCCPAUX Register , Zynq */
#define XADCPS_MIN_VCCPDRO 0xE /**< Minimum VCCPDRO Register , Zynq */
/*@}*/
/**
* @name Alarm Threshold(Limit) Register (ATR) indexes.
* @{
*/
#define XADCPS_ATR_TEMP_UPPER 0 /**< High user Temperature */
#define XADCPS_ATR_VCCINT_UPPER 1 /**< VCCINT high voltage limit register */
#define XADCPS_ATR_VCCAUX_UPPER 2 /**< VCCAUX high voltage limit register */
#define XADCPS_ATR_OT_UPPER 3 /**< VCCAUX high voltage limit register */
#define XADCPS_ATR_TEMP_LOWER 4 /**< Upper Over Temperature limit Reg */
#define XADCPS_ATR_VCCINT_LOWER 5 /**< VCCINT high voltage limit register */
#define XADCPS_ATR_VCCAUX_LOWER 6 /**< VCCAUX low voltage limit register */
#define XADCPS_ATR_OT_LOWER 7 /**< Lower Over Temperature limit */
#define XADCPS_ATR_VBRAM_UPPER_ 8 /**< VRBAM Upper Alarm Reg, 7 Series */
#define XADCPS_ATR_VCCPINT_UPPER 9 /**< VCCPINT Upper Alarm Reg, Zynq */
#define XADCPS_ATR_VCCPAUX_UPPER 0xA /**< VCCPAUX Upper Alarm Reg, Zynq */
#define XADCPS_ATR_VCCPDRO_UPPER 0xB /**< VCCPDRO Upper Alarm Reg, Zynq */
#define XADCPS_ATR_VBRAM_LOWER 0xC /**< VRBAM Lower Alarm Reg, 7 Series */
#define XADCPS_ATR_VCCPINT_LOWER 0xD /**< VCCPINT Lower Alarm Reg , Zynq */
#define XADCPS_ATR_VCCPAUX_LOWER 0xE /**< VCCPAUX Lower Alarm Reg , Zynq */
#define XADCPS_ATR_VCCPDRO_LOWER 0xF /**< VCCPDRO Lower Alarm Reg , Zynq */
/*@}*/
/**
* @name Averaging to be done for the channels.
* @{
*/
#define XADCPS_AVG_0_SAMPLES 0 /**< No Averaging */
#define XADCPS_AVG_16_SAMPLES 1 /**< Average 16 samples */
#define XADCPS_AVG_64_SAMPLES 2 /**< Average 64 samples */
#define XADCPS_AVG_256_SAMPLES 3 /**< Average 256 samples */
/*@}*/
/**
* @name Channel Sequencer Modes of operation
* @{
*/
#define XADCPS_SEQ_MODE_SAFE 0 /**< Default Safe Mode */
#define XADCPS_SEQ_MODE_ONEPASS 1 /**< Onepass through Sequencer */
#define XADCPS_SEQ_MODE_CONTINPASS 2 /**< Continuous Cycling Sequencer */
#define XADCPS_SEQ_MODE_SINGCHAN 3 /**< Single channel -No Sequencing */
#define XADCPS_SEQ_MODE_SIMUL_SAMPLING 4 /**< Simultaneous sampling */
#define XADCPS_SEQ_MODE_INDEPENDENT 8 /**< Independent mode */
/*@}*/
/**
* @name Power Down Modes
* @{
*/
#define XADCPS_PD_MODE_NONE 0 /**< No Power Down */
#define XADCPS_PD_MODE_ADCB 1 /**< Power Down ADC B */
#define XADCPS_PD_MODE_XADC 2 /**< Power Down ADC A and ADC B */
/*@}*/
/**************************** Type Definitions ******************************/
/**
* This typedef contains configuration information for the XADC/ADC
* device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddress; /**< Device base address */
} XAdcPs_Config;
/**
* The driver's instance data. The user is required to allocate a variable
* of this type for every XADC/ADC device in the system. A pointer to
* a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XAdcPs_Config Config; /**< XAdcPs_Config of current device */
u32 IsReady; /**< Device is initialized and ready */
} XAdcPs;
/***************** Macros (Inline Functions) Definitions ********************/
/****************************************************************************/
/**
*
* This macro checks if the XADC device is in Event Sampling mode.
*
* @param InstancePtr is a pointer to the XAdcPs instance.
*
* @return
* - TRUE if the device is in Event Sampling Mode.
* - FALSE if the device is in Continuous Sampling Mode.
*
* @note C-Style signature:
* int XAdcPs_IsEventSamplingMode(XAdcPs *InstancePtr);
*
*****************************************************************************/
#define XAdcPs_IsEventSamplingModeSet(InstancePtr) \
(((XAdcPs_ReadInternalReg(InstancePtr, \
XADCPS_CFR0_OFFSET) & XADCPS_CFR0_EC_MASK) ? \
TRUE : FALSE))
/****************************************************************************/
/**
*
* This macro checks if the XADC device is in External Mux mode.
*
* @param InstancePtr is a pointer to the XAdcPs instance.
*
* @return
* - TRUE if the device is in External Mux Mode.
* - FALSE if the device is NOT in External Mux Mode.
*
* @note C-Style signature:
* int XAdcPs_IsExternalMuxMode(XAdcPs *InstancePtr);
*
*****************************************************************************/
#define XAdcPs_IsExternalMuxModeSet(InstancePtr) \
(((XAdcPs_ReadInternalReg(InstancePtr, \
XADCPS_CFR0_OFFSET) & XADCPS_CFR0_MUX_MASK) ? \
TRUE : FALSE))
/****************************************************************************/
/**
*
* This macro converts XADC Raw Data to Temperature(centigrades).
*
* @param AdcData is the Raw ADC Data from XADC.
*
* @return The Temperature in centigrades.
*
* @note C-Style signature:
* float XAdcPs_RawToTemperature(u32 AdcData);
*
*****************************************************************************/
#define XAdcPs_RawToTemperature(AdcData) \
((((float)(AdcData)/65536.0f)/0.00198421639f ) - 273.15f)
/****************************************************************************/
/**
*
* This macro converts XADC/ADC Raw Data to Voltage(volts).
*
* @param AdcData is the XADC/ADC Raw Data.
*
* @return The Voltage in volts.
*
* @note C-Style signature:
* float XAdcPs_RawToVoltage(u32 AdcData);
*
*****************************************************************************/
#define XAdcPs_RawToVoltage(AdcData) \
((((float)(AdcData))* (3.0f))/65536.0f)
/****************************************************************************/
/**
*
* This macro converts Temperature in centigrades to XADC/ADC Raw Data.
*
* @param Temperature is the Temperature in centigrades to be
* converted to XADC/ADC Raw Data.
*
* @return The XADC/ADC Raw Data.
*
* @note C-Style signature:
* int XAdcPs_TemperatureToRaw(float Temperature);
*
*****************************************************************************/
#define XAdcPs_TemperatureToRaw(Temperature) \
((int)(((Temperature) + 273.15f)*65536.0f*0.00198421639f))
/****************************************************************************/
/**
*
* This macro converts Voltage in Volts to XADC/ADC Raw Data.
*
* @param Voltage is the Voltage in volts to be converted to
* XADC/ADC Raw Data.
*
* @return The XADC/ADC Raw Data.
*
* @note C-Style signature:
* int XAdcPs_VoltageToRaw(float Voltage);
*
*****************************************************************************/
#define XAdcPs_VoltageToRaw(Voltage) \
((int)((Voltage)*65536.0f/3.0f))
/****************************************************************************/
/**
*
* This macro is used for writing to the XADC Registers using the
* command FIFO.
*
* @param InstancePtr is a pointer to the XAdcPs instance.
* @param Data is the value to be written to XADC register.
*
* @return None.
*
* @note C-Style signature:
* void XAdcPs_WriteFifo(XAdcPs *InstancePtr, u32 Data);
*
*****************************************************************************/
#define XAdcPs_WriteFifo(InstancePtr, Data) \
XAdcPs_WriteReg((InstancePtr)->Config.BaseAddress, \
XADCPS_CMDFIFO_OFFSET, Data);
/****************************************************************************/
/**
*
* This macro is used for reading from the XADC Registers using the
* data FIFO.
*
* @param InstancePtr is a pointer to the XAdcPs instance.
*
* @return Data read from the FIFO
*
* @note C-Style signature:
* u32 XAdcPs_ReadFifo(XAdcPs *InstancePtr);
*
*****************************************************************************/
#define XAdcPs_ReadFifo(InstancePtr) \
XAdcPs_ReadReg((InstancePtr)->Config.BaseAddress, \
XADCPS_RDFIFO_OFFSET);
/************************** Function Prototypes *****************************/
/**
* Functions in xadcps_sinit.c
*/
XAdcPs_Config *XAdcPs_LookupConfig(u16 DeviceId);
/**
* Functions in xadcps.c
*/
int XAdcPs_CfgInitialize(XAdcPs *InstancePtr,
XAdcPs_Config *ConfigPtr,
u32 EffectiveAddr);
u32 XAdcPs_GetStatus(XAdcPs *InstancePtr);
u32 XAdcPs_GetAlarmOutputStatus(XAdcPs *InstancePtr);
void XAdcPs_StartAdcConversion(XAdcPs *InstancePtr);
void XAdcPs_Reset(XAdcPs *InstancePtr);
u16 XAdcPs_GetAdcData(XAdcPs *InstancePtr, u8 Channel);
u16 XAdcPs_GetCalibCoefficient(XAdcPs *InstancePtr, u8 CoeffType);
u16 XAdcPs_GetMinMaxMeasurement(XAdcPs *InstancePtr, u8 MeasurementType);
void XAdcPs_SetAvg(XAdcPs *InstancePtr, u8 Average);
u8 XAdcPs_GetAvg(XAdcPs *InstancePtr);
int XAdcPs_SetSingleChParams(XAdcPs *InstancePtr,
u8 Channel,
int IncreaseAcqCycles,
int IsEventMode,
int IsDifferentialMode);
void XAdcPs_SetAlarmEnables(XAdcPs *InstancePtr, u16 AlmEnableMask);
u16 XAdcPs_GetAlarmEnables(XAdcPs *InstancePtr);
void XAdcPs_SetCalibEnables(XAdcPs *InstancePtr, u16 Calibration);
u16 XAdcPs_GetCalibEnables(XAdcPs *InstancePtr);
void XAdcPs_SetSequencerMode(XAdcPs *InstancePtr, u8 SequencerMode);
u8 XAdcPs_GetSequencerMode(XAdcPs *InstancePtr);
void XAdcPs_SetAdcClkDivisor(XAdcPs *InstancePtr, u8 Divisor);
u8 XAdcPs_GetAdcClkDivisor(XAdcPs *InstancePtr);
int XAdcPs_SetSeqChEnables(XAdcPs *InstancePtr, u32 ChEnableMask);
u32 XAdcPs_GetSeqChEnables(XAdcPs *InstancePtr);
int XAdcPs_SetSeqAvgEnables(XAdcPs *InstancePtr, u32 AvgEnableChMask);
u32 XAdcPs_GetSeqAvgEnables(XAdcPs *InstancePtr);
int XAdcPs_SetSeqInputMode(XAdcPs *InstancePtr, u32 InputModeChMask);
u32 XAdcPs_GetSeqInputMode(XAdcPs *InstancePtr);
int XAdcPs_SetSeqAcqTime(XAdcPs *InstancePtr, u32 AcqCyclesChMask);
u32 XAdcPs_GetSeqAcqTime(XAdcPs *InstancePtr);
void XAdcPs_SetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg, u16 Value);
u16 XAdcPs_GetAlarmThreshold(XAdcPs *InstancePtr, u8 AlarmThrReg);
void XAdcPs_EnableUserOverTemp(XAdcPs *InstancePtr);
void XAdcPs_DisableUserOverTemp(XAdcPs *InstancePtr);
void XAdcPs_SetSequencerEvent(XAdcPs *InstancePtr, int IsEventMode);
int XAdcPs_GetSamplingMode(XAdcPs *InstancePtr);
void XAdcPs_SetMuxMode(XAdcPs *InstancePtr, int MuxMode, u8 Channel);
void XAdcPs_SetPowerdownMode(XAdcPs *InstancePtr, u32 Mode);
u32 XAdcPs_GetPowerdownMode(XAdcPs *InstancePtr);
/**
* Functions in xadcps_selftest.c
*/
int XAdcPs_SelfTest(XAdcPs *InstancePtr);
/**
* Functions in xadcps_intr.c
*/
void XAdcPs_IntrEnable(XAdcPs *InstancePtr, u32 Mask);
void XAdcPs_IntrDisable(XAdcPs *InstancePtr, u32 Mask);
u32 XAdcPs_IntrGetEnabled(XAdcPs *InstancePtr);
u32 XAdcPs_IntrGetStatus(XAdcPs *InstancePtr);
void XAdcPs_IntrClear(XAdcPs *InstancePtr, u32 Mask);
#ifdef __cplusplus
}
#endif
#endif /* End of protection macro. */
/** @} */
@@ -1,498 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2011 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xadcps_hw.h
* @addtogroup xadcps_v2_3
* @{
*
* This header file contains identifiers and basic driver functions (or
* macros) that can be used to access the XADC device through the Device
* Config Interface of the Zynq.
*
*
* Refer to the device specification for more information about this driver.
*
* @note None.
*
*
* <pre>
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------------
* 1.00a bss 12/22/11 First release based on the XPS/AXI xadc driver
* 1.03a bss 11/01/13 Modified macros to use correct Register offsets
* CR#749687
*
* </pre>
*
*****************************************************************************/
#ifndef XADCPS_HW_H /* Prevent circular inclusions */
#define XADCPS_HW_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions ****************************/
/**@name Register offsets of XADC in the Device Config
*
* The following constants provide access to each of the registers of the
* XADC device.
* @{
*/
#define XADCPS_CFG_OFFSET 0x00 /**< Configuration Register */
#define XADCPS_INT_STS_OFFSET 0x04 /**< Interrupt Status Register */
#define XADCPS_INT_MASK_OFFSET 0x08 /**< Interrupt Mask Register */
#define XADCPS_MSTS_OFFSET 0x0C /**< Misc status register */
#define XADCPS_CMDFIFO_OFFSET 0x10 /**< Command FIFO Register */
#define XADCPS_RDFIFO_OFFSET 0x14 /**< Read FIFO Register */
#define XADCPS_MCTL_OFFSET 0x18 /**< Misc control register */
/* @} */
/** @name XADC Config Register Bit definitions
* @{
*/
#define XADCPS_CFG_ENABLE_MASK 0x80000000 /**< Enable access from PS mask */
#define XADCPS_CFG_CFIFOTH_MASK 0x00F00000 /**< Command FIFO Threshold mask */
#define XADCPS_CFG_DFIFOTH_MASK 0x000F0000 /**< Data FIFO Threshold mask */
#define XADCPS_CFG_WEDGE_MASK 0x00002000 /**< Write Edge Mask */
#define XADCPS_CFG_REDGE_MASK 0x00001000 /**< Read Edge Mask */
#define XADCPS_CFG_TCKRATE_MASK 0x00000300 /**< Clock freq control */
#define XADCPS_CFG_IGAP_MASK 0x0000001F /**< Idle Gap between
* successive commands */
/* @} */
/** @name XADC Interrupt Status/Mask Register Bit definitions
*
* The definitions are same for the Interrupt Status Register and
* Interrupt Mask Register. They are defined only once.
* @{
*/
#define XADCPS_INTX_ALL_MASK 0x000003FF /**< Alarm Signals Mask */
#define XADCPS_INTX_CFIFO_LTH_MASK 0x00000200 /**< CMD FIFO less than threshold */
#define XADCPS_INTX_DFIFO_GTH_MASK 0x00000100 /**< Data FIFO greater than threshold */
#define XADCPS_INTX_OT_MASK 0x00000080 /**< Over temperature Alarm Status */
#define XADCPS_INTX_ALM_ALL_MASK 0x0000007F /**< Alarm Signals Mask */
#define XADCPS_INTX_ALM6_MASK 0x00000040 /**< Alarm 6 Mask */
#define XADCPS_INTX_ALM5_MASK 0x00000020 /**< Alarm 5 Mask */
#define XADCPS_INTX_ALM4_MASK 0x00000010 /**< Alarm 4 Mask */
#define XADCPS_INTX_ALM3_MASK 0x00000008 /**< Alarm 3 Mask */
#define XADCPS_INTX_ALM2_MASK 0x00000004 /**< Alarm 2 Mask */
#define XADCPS_INTX_ALM1_MASK 0x00000002 /**< Alarm 1 Mask */
#define XADCPS_INTX_ALM0_MASK 0x00000001 /**< Alarm 0 Mask */
/* @} */
/** @name XADC Miscellaneous Register Bit definitions
* @{
*/
#define XADCPS_MSTS_CFIFO_LVL_MASK 0x000F0000 /**< Command FIFO Level mask */
#define XADCPS_MSTS_DFIFO_LVL_MASK 0x0000F000 /**< Data FIFO Level Mask */
#define XADCPS_MSTS_CFIFOF_MASK 0x00000800 /**< Command FIFO Full Mask */
#define XADCPS_MSTS_CFIFOE_MASK 0x00000400 /**< Command FIFO Empty Mask */
#define XADCPS_MSTS_DFIFOF_MASK 0x00000200 /**< Data FIFO Full Mask */
#define XADCPS_MSTS_DFIFOE_MASK 0x00000100 /**< Data FIFO Empty Mask */
#define XADCPS_MSTS_OT_MASK 0x00000080 /**< Over Temperature Mask */
#define XADCPS_MSTS_ALM_MASK 0x0000007F /**< Alarms Mask */
/* @} */
/** @name XADC Miscellaneous Control Register Bit definitions
* @{
*/
#define XADCPS_MCTL_RESET_MASK 0x00000010 /**< Reset XADC */
#define XADCPS_MCTL_FLUSH_MASK 0x00000001 /**< Flush the FIFOs */
/* @} */
/**@name Internal Register offsets of the XADC
*
* The following constants provide access to each of the internal registers of
* the XADC device.
* @{
*/
/*
* XADC Internal Channel Registers
*/
#define XADCPS_TEMP_OFFSET 0x00 /**< On-chip Temperature Reg */
#define XADCPS_VCCINT_OFFSET 0x01 /**< On-chip VCCINT Data Reg */
#define XADCPS_VCCAUX_OFFSET 0x02 /**< On-chip VCCAUX Data Reg */
#define XADCPS_VPVN_OFFSET 0x03 /**< ADC out of VP/VN */
#define XADCPS_VREFP_OFFSET 0x04 /**< On-chip VREFP Data Reg */
#define XADCPS_VREFN_OFFSET 0x05 /**< On-chip VREFN Data Reg */
#define XADCPS_VBRAM_OFFSET 0x06 /**< On-chip VBRAM , 7 Series */
#define XADCPS_ADC_A_SUPPLY_CALIB_OFFSET 0x08 /**< ADC A Supply Offset Reg */
#define XADCPS_ADC_A_OFFSET_CALIB_OFFSET 0x09 /**< ADC A Offset Data Reg */
#define XADCPS_ADC_A_GAINERR_CALIB_OFFSET 0x0A /**< ADC A Gain Error Reg */
#define XADCPS_VCCPINT_OFFSET 0x0D /**< On-chip VCCPINT Reg, Zynq */
#define XADCPS_VCCPAUX_OFFSET 0x0E /**< On-chip VCCPAUX Reg, Zynq */
#define XADCPS_VCCPDRO_OFFSET 0x0F /**< On-chip VCCPDRO Reg, Zynq */
/*
* XADC External Channel Registers
*/
#define XADCPS_AUX00_OFFSET 0x10 /**< ADC out of VAUXP0/VAUXN0 */
#define XADCPS_AUX01_OFFSET 0x11 /**< ADC out of VAUXP1/VAUXN1 */
#define XADCPS_AUX02_OFFSET 0x12 /**< ADC out of VAUXP2/VAUXN2 */
#define XADCPS_AUX03_OFFSET 0x13 /**< ADC out of VAUXP3/VAUXN3 */
#define XADCPS_AUX04_OFFSET 0x14 /**< ADC out of VAUXP4/VAUXN4 */
#define XADCPS_AUX05_OFFSET 0x15 /**< ADC out of VAUXP5/VAUXN5 */
#define XADCPS_AUX06_OFFSET 0x16 /**< ADC out of VAUXP6/VAUXN6 */
#define XADCPS_AUX07_OFFSET 0x17 /**< ADC out of VAUXP7/VAUXN7 */
#define XADCPS_AUX08_OFFSET 0x18 /**< ADC out of VAUXP8/VAUXN8 */
#define XADCPS_AUX09_OFFSET 0x19 /**< ADC out of VAUXP9/VAUXN9 */
#define XADCPS_AUX10_OFFSET 0x1A /**< ADC out of VAUXP10/VAUXN10 */
#define XADCPS_AUX11_OFFSET 0x1B /**< ADC out of VAUXP11/VAUXN11 */
#define XADCPS_AUX12_OFFSET 0x1C /**< ADC out of VAUXP12/VAUXN12 */
#define XADCPS_AUX13_OFFSET 0x1D /**< ADC out of VAUXP13/VAUXN13 */
#define XADCPS_AUX14_OFFSET 0x1E /**< ADC out of VAUXP14/VAUXN14 */
#define XADCPS_AUX15_OFFSET 0x1F /**< ADC out of VAUXP15/VAUXN15 */
/*
* XADC Registers for Maximum/Minimum data captured for the
* on chip Temperature/VCCINT/VCCAUX data.
*/
#define XADCPS_MAX_TEMP_OFFSET 0x20 /**< Max Temperature Reg */
#define XADCPS_MAX_VCCINT_OFFSET 0x21 /**< Max VCCINT Register */
#define XADCPS_MAX_VCCAUX_OFFSET 0x22 /**< Max VCCAUX Register */
#define XADCPS_MAX_VCCBRAM_OFFSET 0x23 /**< Max BRAM Register, 7 series */
#define XADCPS_MIN_TEMP_OFFSET 0x24 /**< Min Temperature Reg */
#define XADCPS_MIN_VCCINT_OFFSET 0x25 /**< Min VCCINT Register */
#define XADCPS_MIN_VCCAUX_OFFSET 0x26 /**< Min VCCAUX Register */
#define XADCPS_MIN_VCCBRAM_OFFSET 0x27 /**< Min BRAM Register, 7 series */
#define XADCPS_MAX_VCCPINT_OFFSET 0x28 /**< Max VCCPINT Register, Zynq */
#define XADCPS_MAX_VCCPAUX_OFFSET 0x29 /**< Max VCCPAUX Register, Zynq */
#define XADCPS_MAX_VCCPDRO_OFFSET 0x2A /**< Max VCCPDRO Register, Zynq */
#define XADCPS_MIN_VCCPINT_OFFSET 0x2C /**< Min VCCPINT Register, Zynq */
#define XADCPS_MIN_VCCPAUX_OFFSET 0x2D /**< Min VCCPAUX Register, Zynq */
#define XADCPS_MIN_VCCPDRO_OFFSET 0x2E /**< Min VCCPDRO Register,Zynq */
/* Undefined 0x2F to 0x3E */
#define XADCPS_FLAG_OFFSET 0x3F /**< Flag Register */
/*
* XADC Configuration Registers
*/
#define XADCPS_CFR0_OFFSET 0x40 /**< Configuration Register 0 */
#define XADCPS_CFR1_OFFSET 0x41 /**< Configuration Register 1 */
#define XADCPS_CFR2_OFFSET 0x42 /**< Configuration Register 2 */
/* Test Registers 0x43 to 0x47 */
/*
* XADC Sequence Registers
*/
#define XADCPS_SEQ00_OFFSET 0x48 /**< Seq Reg 00 Adc Channel Selection */
#define XADCPS_SEQ01_OFFSET 0x49 /**< Seq Reg 01 Adc Channel Selection */
#define XADCPS_SEQ02_OFFSET 0x4A /**< Seq Reg 02 Adc Average Enable */
#define XADCPS_SEQ03_OFFSET 0x4B /**< Seq Reg 03 Adc Average Enable */
#define XADCPS_SEQ04_OFFSET 0x4C /**< Seq Reg 04 Adc Input Mode Select */
#define XADCPS_SEQ05_OFFSET 0x4D /**< Seq Reg 05 Adc Input Mode Select */
#define XADCPS_SEQ06_OFFSET 0x4E /**< Seq Reg 06 Adc Acquisition Select */
#define XADCPS_SEQ07_OFFSET 0x4F /**< Seq Reg 07 Adc Acquisition Select */
/*
* XADC Alarm Threshold/Limit Registers (ATR)
*/
#define XADCPS_ATR_TEMP_UPPER_OFFSET 0x50 /**< Temp Upper Alarm Register */
#define XADCPS_ATR_VCCINT_UPPER_OFFSET 0x51 /**< VCCINT Upper Alarm Reg */
#define XADCPS_ATR_VCCAUX_UPPER_OFFSET 0x52 /**< VCCAUX Upper Alarm Reg */
#define XADCPS_ATR_OT_UPPER_OFFSET 0x53 /**< Over Temp Upper Alarm Reg */
#define XADCPS_ATR_TEMP_LOWER_OFFSET 0x54 /**< Temp Lower Alarm Register */
#define XADCPS_ATR_VCCINT_LOWER_OFFSET 0x55 /**< VCCINT Lower Alarm Reg */
#define XADCPS_ATR_VCCAUX_LOWER_OFFSET 0x56 /**< VCCAUX Lower Alarm Reg */
#define XADCPS_ATR_OT_LOWER_OFFSET 0x57 /**< Over Temp Lower Alarm Reg */
#define XADCPS_ATR_VBRAM_UPPER_OFFSET 0x58 /**< VBRAM Upper Alarm, 7 series */
#define XADCPS_ATR_VCCPINT_UPPER_OFFSET 0x59 /**< VCCPINT Upper Alarm, Zynq */
#define XADCPS_ATR_VCCPAUX_UPPER_OFFSET 0x5A /**< VCCPAUX Upper Alarm, Zynq */
#define XADCPS_ATR_VCCPDRO_UPPER_OFFSET 0x5B /**< VCCPDRO Upper Alarm, Zynq */
#define XADCPS_ATR_VBRAM_LOWER_OFFSET 0x5C /**< VRBAM Lower Alarm, 7 Series */
#define XADCPS_ATR_VCCPINT_LOWER_OFFSET 0x5D /**< VCCPINT Lower Alarm, Zynq */
#define XADCPS_ATR_VCCPAUX_LOWER_OFFSET 0x5E /**< VCCPAUX Lower Alarm, Zynq */
#define XADCPS_ATR_VCCPDRO_LOWER_OFFSET 0x5F /**< VCCPDRO Lower Alarm, Zynq */
/* Undefined 0x60 to 0x7F */
/*@}*/
/**
* @name Configuration Register 0 (CFR0) mask(s)
* @{
*/
#define XADCPS_CFR0_CAL_AVG_MASK 0x8000 /**< Averaging enable Mask */
#define XADCPS_CFR0_AVG_VALID_MASK 0x3000 /**< Averaging bit Mask */
#define XADCPS_CFR0_AVG1_MASK 0x0000 /**< No Averaging */
#define XADCPS_CFR0_AVG16_MASK 0x1000 /**< Average 16 samples */
#define XADCPS_CFR0_AVG64_MASK 0x2000 /**< Average 64 samples */
#define XADCPS_CFR0_AVG256_MASK 0x3000 /**< Average 256 samples */
#define XADCPS_CFR0_AVG_SHIFT 12 /**< Averaging bits shift */
#define XADCPS_CFR0_MUX_MASK 0x0800 /**< External Mask Enable */
#define XADCPS_CFR0_DU_MASK 0x0400 /**< Bipolar/Unipolar mode */
#define XADCPS_CFR0_EC_MASK 0x0200 /**< Event driven/
* Continuous mode selection
*/
#define XADCPS_CFR0_ACQ_MASK 0x0100 /**< Add acquisition by 6 ADCCLK */
#define XADCPS_CFR0_CHANNEL_MASK 0x001F /**< Channel number bit Mask */
/*@}*/
/**
* @name Configuration Register 1 (CFR1) mask(s)
* @{
*/
#define XADCPS_CFR1_SEQ_VALID_MASK 0xF000 /**< Sequence bit Mask */
#define XADCPS_CFR1_SEQ_SAFEMODE_MASK 0x0000 /**< Default Safe Mode */
#define XADCPS_CFR1_SEQ_ONEPASS_MASK 0x1000 /**< Onepass through Seq */
#define XADCPS_CFR1_SEQ_CONTINPASS_MASK 0x2000 /**< Continuous Cycling Seq */
#define XADCPS_CFR1_SEQ_SINGCHAN_MASK 0x3000 /**< Single channel - No Seq */
#define XADCPS_CFR1_SEQ_SIMUL_SAMPLING_MASK 0x4000 /**< Simulataneous Sampling Mask */
#define XADCPS_CFR1_SEQ_INDEPENDENT_MASK 0x8000 /**< Independent Mode */
#define XADCPS_CFR1_SEQ_SHIFT 12 /**< Sequence bit shift */
#define XADCPS_CFR1_ALM_VCCPDRO_MASK 0x0800 /**< Alm 6 - VCCPDRO, Zynq */
#define XADCPS_CFR1_ALM_VCCPAUX_MASK 0x0400 /**< Alm 5 - VCCPAUX, Zynq */
#define XADCPS_CFR1_ALM_VCCPINT_MASK 0x0200 /**< Alm 4 - VCCPINT, Zynq */
#define XADCPS_CFR1_ALM_VBRAM_MASK 0x0100 /**< Alm 3 - VBRAM, 7 series */
#define XADCPS_CFR1_CAL_VALID_MASK 0x00F0 /**< Valid Calibration Mask */
#define XADCPS_CFR1_CAL_PS_GAIN_OFFSET_MASK 0x0080 /**< Calibration 3 -Power
Supply Gain/Offset
Enable */
#define XADCPS_CFR1_CAL_PS_OFFSET_MASK 0x0040 /**< Calibration 2 -Power
Supply Offset Enable */
#define XADCPS_CFR1_CAL_ADC_GAIN_OFFSET_MASK 0x0020 /**< Calibration 1 -ADC Gain
Offset Enable */
#define XADCPS_CFR1_CAL_ADC_OFFSET_MASK 0x0010 /**< Calibration 0 -ADC Offset
Enable */
#define XADCPS_CFR1_CAL_DISABLE_MASK 0x0000 /**< No Calibration */
#define XADCPS_CFR1_ALM_ALL_MASK 0x0F0F /**< Mask for all alarms */
#define XADCPS_CFR1_ALM_VCCAUX_MASK 0x0008 /**< Alarm 2 - VCCAUX Enable */
#define XADCPS_CFR1_ALM_VCCINT_MASK 0x0004 /**< Alarm 1 - VCCINT Enable */
#define XADCPS_CFR1_ALM_TEMP_MASK 0x0002 /**< Alarm 0 - Temperature */
#define XADCPS_CFR1_OT_MASK 0x0001 /**< Over Temperature Enable */
/*@}*/
/**
* @name Configuration Register 2 (CFR2) mask(s)
* @{
*/
#define XADCPS_CFR2_CD_VALID_MASK 0xFF00 /**<Clock Divisor bit Mask */
#define XADCPS_CFR2_CD_SHIFT 8 /**<Num of shift on division */
#define XADCPS_CFR2_CD_MIN 8 /**<Minimum value of divisor */
#define XADCPS_CFR2_CD_MAX 255 /**<Maximum value of divisor */
#define XADCPS_CFR2_CD_MIN 8 /**<Minimum value of divisor */
#define XADCPS_CFR2_PD_MASK 0x0030 /**<Power Down Mask */
#define XADCPS_CFR2_PD_XADC_MASK 0x0030 /**<Power Down XADC Mask */
#define XADCPS_CFR2_PD_ADC1_MASK 0x0020 /**<Power Down ADC1 Mask */
#define XADCPS_CFR2_PD_SHIFT 4 /**<Power Down Shift */
/*@}*/
/**
* @name Sequence Register (SEQ) Bit Definitions
* @{
*/
#define XADCPS_SEQ_CH_CALIB 0x00000001 /**< ADC Calibration Channel */
#define XADCPS_SEQ_CH_VCCPINT 0x00000020 /**< VCCPINT, Zynq Only */
#define XADCPS_SEQ_CH_VCCPAUX 0x00000040 /**< VCCPAUX, Zynq Only */
#define XADCPS_SEQ_CH_VCCPDRO 0x00000080 /**< VCCPDRO, Zynq Only */
#define XADCPS_SEQ_CH_TEMP 0x00000100 /**< On Chip Temperature Channel */
#define XADCPS_SEQ_CH_VCCINT 0x00000200 /**< VCCINT Channel */
#define XADCPS_SEQ_CH_VCCAUX 0x00000400 /**< VCCAUX Channel */
#define XADCPS_SEQ_CH_VPVN 0x00000800 /**< VP/VN analog inputs Channel */
#define XADCPS_SEQ_CH_VREFP 0x00001000 /**< VREFP Channel */
#define XADCPS_SEQ_CH_VREFN 0x00002000 /**< VREFN Channel */
#define XADCPS_SEQ_CH_VBRAM 0x00004000 /**< VBRAM Channel, 7 series */
#define XADCPS_SEQ_CH_AUX00 0x00010000 /**< 1st Aux Channel */
#define XADCPS_SEQ_CH_AUX01 0x00020000 /**< 2nd Aux Channel */
#define XADCPS_SEQ_CH_AUX02 0x00040000 /**< 3rd Aux Channel */
#define XADCPS_SEQ_CH_AUX03 0x00080000 /**< 4th Aux Channel */
#define XADCPS_SEQ_CH_AUX04 0x00100000 /**< 5th Aux Channel */
#define XADCPS_SEQ_CH_AUX05 0x00200000 /**< 6th Aux Channel */
#define XADCPS_SEQ_CH_AUX06 0x00400000 /**< 7th Aux Channel */
#define XADCPS_SEQ_CH_AUX07 0x00800000 /**< 8th Aux Channel */
#define XADCPS_SEQ_CH_AUX08 0x01000000 /**< 9th Aux Channel */
#define XADCPS_SEQ_CH_AUX09 0x02000000 /**< 10th Aux Channel */
#define XADCPS_SEQ_CH_AUX10 0x04000000 /**< 11th Aux Channel */
#define XADCPS_SEQ_CH_AUX11 0x08000000 /**< 12th Aux Channel */
#define XADCPS_SEQ_CH_AUX12 0x10000000 /**< 13th Aux Channel */
#define XADCPS_SEQ_CH_AUX13 0x20000000 /**< 14th Aux Channel */
#define XADCPS_SEQ_CH_AUX14 0x40000000 /**< 15th Aux Channel */
#define XADCPS_SEQ_CH_AUX15 0x80000000 /**< 16th Aux Channel */
#define XADCPS_SEQ00_CH_VALID_MASK 0x7FE1 /**< Mask for the valid channels */
#define XADCPS_SEQ01_CH_VALID_MASK 0xFFFF /**< Mask for the valid channels */
#define XADCPS_SEQ02_CH_VALID_MASK 0x7FE0 /**< Mask for the valid channels */
#define XADCPS_SEQ03_CH_VALID_MASK 0xFFFF /**< Mask for the valid channels */
#define XADCPS_SEQ04_CH_VALID_MASK 0x0800 /**< Mask for the valid channels */
#define XADCPS_SEQ05_CH_VALID_MASK 0xFFFF /**< Mask for the valid channels */
#define XADCPS_SEQ06_CH_VALID_MASK 0x0800 /**< Mask for the valid channels */
#define XADCPS_SEQ07_CH_VALID_MASK 0xFFFF /**< Mask for the valid channels */
#define XADCPS_SEQ_CH_AUX_SHIFT 16 /**< Shift for the Aux Channel */
/*@}*/
/**
* @name OT Upper Alarm Threshold Register Bit Definitions
* @{
*/
#define XADCPS_ATR_OT_UPPER_ENB_MASK 0x000F /**< Mask for OT enable */
#define XADCPS_ATR_OT_UPPER_VAL_MASK 0xFFF0 /**< Mask for OT value */
#define XADCPS_ATR_OT_UPPER_VAL_SHIFT 4 /**< Shift for OT value */
#define XADCPS_ATR_OT_UPPER_ENB_VAL 0x0003 /**< Value for OT enable */
#define XADCPS_ATR_OT_UPPER_VAL_MAX 0x0FFF /**< Max OT value */
/*@}*/
/**
* @name JTAG DRP Bit Definitions
* @{
*/
#define XADCPS_JTAG_DATA_MASK 0x0000FFFF /**< Mask for the Data */
#define XADCPS_JTAG_ADDR_MASK 0x03FF0000 /**< Mask for the Addr */
#define XADCPS_JTAG_ADDR_SHIFT 16 /**< Shift for the Addr */
#define XADCPS_JTAG_CMD_MASK 0x3C000000 /**< Mask for the Cmd */
#define XADCPS_JTAG_CMD_WRITE_MASK 0x08000000 /**< Mask for CMD Write */
#define XADCPS_JTAG_CMD_READ_MASK 0x04000000 /**< Mask for CMD Read */
#define XADCPS_JTAG_CMD_SHIFT 26 /**< Shift for the Cmd */
/*@}*/
/** @name Unlock Register Definitions
* @{
*/
#define XADCPS_UNLK_OFFSET 0x034 /**< Unlock Register */
#define XADCPS_UNLK_VALUE 0x757BDF0D /**< Unlock Value */
/* @} */
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
*
* Read a register of the XADC device. This macro provides register
* access to all registers using the register offsets defined above.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset is the offset of the register to read.
*
* @return The contents of the register.
*
* @note C-style Signature:
* u32 XAdcPs_ReadReg(u32 BaseAddress, u32 RegOffset);
*
******************************************************************************/
#define XAdcPs_ReadReg(BaseAddress, RegOffset) \
(Xil_In32((BaseAddress) + (RegOffset)))
/*****************************************************************************/
/**
*
* Write a register of the XADC device. This macro provides
* register access to all registers using the register offsets defined above.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset is the offset of the register to write.
* @param Data is the value to write to the register.
*
* @return None.
*
* @note C-style Signature:
* void XAdcPs_WriteReg(u32 BaseAddress,
* u32 RegOffset,u32 Data)
*
******************************************************************************/
#define XAdcPs_WriteReg(BaseAddress, RegOffset, Data) \
(Xil_Out32((BaseAddress) + (RegOffset), (Data)))
/************************** Function Prototypes ******************************/
/*****************************************************************************/
/**
*
* Formats the data to be written to the the XADC registers.
*
* @param RegOffset is the offset of the Register
* @param Data is the data to be written to the Register if it is
* a write.
* @param ReadWrite specifies whether it is a Read or a Write.
* Use 0 for Read, 1 for Write.
*
* @return None.
*
* @note C-style Signature:
* void XAdcPs_FormatWriteData(u32 RegOffset,
* u16 Data, int ReadWrite)
*
******************************************************************************/
#define XAdcPs_FormatWriteData(RegOffset, Data, ReadWrite) \
((ReadWrite ? XADCPS_JTAG_CMD_WRITE_MASK : XADCPS_JTAG_CMD_READ_MASK ) | \
((RegOffset << XADCPS_JTAG_ADDR_SHIFT) & XADCPS_JTAG_ADDR_MASK) | \
(Data & XADCPS_JTAG_DATA_MASK))
#ifdef __cplusplus
}
#endif
#endif /* End of protection macro. */
/** @} */
@@ -1,127 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xbasic_types.h
*
*
* @note Dummy File for backwards compatibility
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a adk 1/31/14 Added in bsp common folder for backward compatibility
* 7.0 aru 01/21/19 Modified the typedef of u32,u16,u8
* 7.0 aru 02/06/19 Included stdint.h and stddef.h
* </pre>
*
******************************************************************************/
#ifndef XBASIC_TYPES_H /* prevent circular inclusions */
#define XBASIC_TYPES_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
/** @name Legacy types
* Deprecated legacy types.
* @{
*/
typedef uint8_t Xuint8; /**< unsigned 8-bit */
typedef char Xint8; /**< signed 8-bit */
typedef uint16_t Xuint16; /**< unsigned 16-bit */
typedef short Xint16; /**< signed 16-bit */
typedef uint32_t Xuint32; /**< unsigned 32-bit */
typedef long Xint32; /**< signed 32-bit */
typedef float Xfloat32; /**< 32-bit floating point */
typedef double Xfloat64; /**< 64-bit double precision FP */
typedef unsigned long Xboolean; /**< boolean (XTRUE or XFALSE) */
#if !defined __XUINT64__
typedef struct
{
Xuint32 Upper;
Xuint32 Lower;
} Xuint64;
#endif
/** @name New types
* New simple types.
* @{
*/
#ifndef __KERNEL__
#ifndef XIL_TYPES_H
typedef Xuint32 u32;
typedef Xuint16 u16;
typedef Xuint8 u8;
#endif
#else
#include <linux/types.h>
#endif
#ifndef TRUE
# define TRUE 1U
#endif
#ifndef FALSE
# define FALSE 0U
#endif
#ifndef NULL
#define NULL 0U
#endif
/*
* Xilinx NULL, TRUE and FALSE legacy support. Deprecated.
* Please use NULL, TRUE and FALSE
*/
#define XNULL NULL
#define XTRUE TRUE
#define XFALSE FALSE
/*
* This file is deprecated and users
* should use xil_types.h and xil_assert.h\n\r
*/
#warning The xbasics_type.h file is deprecated and users should use xil_types.h and xil_assert.
#warning Please refer the Standalone BSP UG647 for further details
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
@@ -1,223 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xbram.h
* @addtogroup bram_v4_2
* @{
* @details
*
* If ECC is not enabled, this driver exists only to allow the tools to
* create a memory test application and to populate xparameters.h with memory
* range constants. In this case there is no source code.
*
* If ECC is enabled, this file contains the software API definition of the
* Xilinx BRAM Interface Controller (XBram) device driver.
*
* The Xilinx BRAM controller is a soft IP core designed for Xilinx
* FPGAs and contains the following general features:
* - LMB v2.0 bus interfaces with byte enable support
* - Used in conjunction with bram_block peripheral to provide fast BRAM
* memory solution for MicroBlaze ILMB and DLMB ports
* - Supports byte, half-word, and word transfers
* - Supports optional BRAM error correction and detection.
*
* The driver provides interrupt management functions. Implementation of
* interrupt handlers is left to the user. Refer to the provided interrupt
* example in the examples directory for details.
*
* This driver is intended to be RTOS and processor independent. Any needs for
* dynamic memory management, threads or thread mutual exclusion, virtual
* memory, or cache control must be satisfied by the layer above this driver.
*
* <b>Initialization & Configuration</b>
*
* The XBram_Config structure is used by the driver to configure
* itself. This configuration structure is typically created by the tool-chain
* based on HW build properties.
*
* To support multiple runtime loading and initialization strategies employed
* by various operating systems, the driver instance can be initialized as
* follows:
*
* - XBram_CfgInitialize(InstancePtr, CfgPtr, EffectiveAddr) -
* Uses a configuration structure provided by the caller. If running in a
* system with address translation, the provided virtual memory base address
* replaces the physical address present in the configuration structure.
*
* @note
*
* This API utilizes 32 bit I/O to the BRAM registers. With less
* than 32 bits, the unused bits from registers are read as zero and written as
* don't cares.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 3.00a sa 05/11/10 Added ECC support
* 3.01a sa 01/13/12 Changed Selftest API from
* XBram_SelfTest(XBram *InstancePtr) to
* XBram_SelfTest(XBram *InstancePtr, u8 IntMask) and
* fixed a problem with interrupt generation for CR 639274
* Modified Selftest example to return XST_SUCCESS when
* ECC is not enabled and return XST_FAILURE when ECC is
* enabled and Control Base Address is zero (CR 636581)
* Modified Selftest to use correct CorrectableCounterBits
* for CR 635655
* Updated to check CorrectableFailingDataRegs in the case
* of LMB BRAM.
* Added CorrectableFailingDataRegs and
* UncorrectableFailingDataRegs to the config structure to
* distinguish between AXI BRAM and LMB BRAM.
* These registers are not present in the current version of
* the AXI BRAM Controller.
* 3.02a sa 04/16/12 Added test of byte and halfword read-modify-write
* 3.02a sa 04/16/12 Modified driver tcl to sort the address parameters
* to support both xps and vivado designs.
* 3.02a adk 24/4/13 Modified the tcl file to avoid warnings
* when ecc is disabled cr:705002.
* 3.03a bss 05/22/13 Added Xil_DCacheFlushRange in xbram_selftest.c to
* flush the Cache after writing to BRAM in InjectErrors
* API(CR #719011)
* 4.0 adk 19/12/13 Updated as per the New Tcl API's
* 4.1 sk 11/10/15 Used UINTPTR instead of u32 for Baseaddress CR# 867425.
* Changed the prototype of XBram_CfgInitialize API.
* ms 01/23/17 Modified xil_printf statement in main function for all
* examples to ensure that "Successfully ran" and "Failed"
* strings are available in all examples. This is a fix
* for CR-965028.
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
* generation.
* 4.2 ms 04/18/17 Modified tcl file to add suffix U for all macro
* definitions of bram in xparameters.h
* ms 08/07/17 Fixed compilation warnings in xbram_sinit.c
* 4.3 aru 03/23/19 Used UINTPTR instead of u32 for MemBaseAddress and
* MemHighAddress.
* </pre>
*****************************************************************************/
#ifndef XBRAM_H /* prevent circular inclusions */
#define XBRAM_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xbram_hw.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/**
* This typedef contains configuration information for the device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 DataWidth; /**< BRAM data width */
int EccPresent; /**< Is ECC supported in H/W */
int FaultInjectionPresent; /**< Is Fault Injection
* supported in H/W */
int CorrectableFailingRegisters; /**< Is Correctable Failing Registers
* supported in H/W */
int CorrectableFailingDataRegs; /**< Is Correctable Failing Data
* Registers supported in H/W */
int UncorrectableFailingRegisters; /**< Is Un-correctable Failing
* Registers supported in H/W */
int UncorrectableFailingDataRegs; /**< Is Un-correctable Failing Data
* Registers supported in H/W */
int EccStatusInterruptPresent; /**< Are ECC status and interrupts
* supported in H/W */
int CorrectableCounterBits; /**< Number of bits in the
* Correctable Error Counter */
int EccOnOffRegister; /**< Is ECC on/off register supported
* in h/w */
int EccOnOffResetValue; /**< Reset value of the ECC on/off
* register in h/w */
int WriteAccess; /**< Is write access enabled in
* h/w */
UINTPTR MemBaseAddress; /**< Device memory base address */
UINTPTR MemHighAddress; /**< Device memory high address */
UINTPTR CtrlBaseAddress; /**< Device register base address.*/
UINTPTR CtrlHighAddress; /**< Device register base address.*/
} XBram_Config;
/**
* The XBram driver instance data. The user is required to
* allocate a variable of this type for every BRAM device in the
* system. A pointer to a variable of this type is then passed to the driver
* API functions.
*/
typedef struct {
XBram_Config Config; /* BRAM config structure */
u32 IsReady; /* Device is initialized and ready */
} XBram;
/***************** Macros (Inline Functions) Definitions ********************/
/************************** Function Prototypes *****************************/
/*
* Functions in xbram_sinit.c
*/
XBram_Config *XBram_LookupConfig(u16 DeviceId);
/*
* Functions implemented in xbram.c
*/
int XBram_CfgInitialize(XBram *InstancePtr, XBram_Config *Config,
UINTPTR EffectiveAddr);
/*
* Functions implemented in xbram_selftest.c
*/
int XBram_SelfTest(XBram *InstancePtr, u8 IntMask);
/*
* Functions implemented in xbram_intr.c
*/
void XBram_InterruptEnable(XBram *InstancePtr, u32 Mask);
void XBram_InterruptDisable(XBram *InstancePtr, u32 Mask);
void XBram_InterruptClear(XBram *InstancePtr, u32 Mask);
u32 XBram_InterruptGetEnabled(XBram *InstancePtr);
u32 XBram_InterruptGetStatus(XBram *InstancePtr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */
@@ -1,405 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2011 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xbram_hw.h
* @addtogroup bram_v4_2
* @{
*
* This header file contains identifiers and driver functions (or
* macros) that can be used to access the device. The user should refer to the
* hardware device specification for more details of the device operation.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sa 24/11/10 First release
* </pre>
*
******************************************************************************/
#ifndef XBRAM_HW_H /* prevent circular inclusions */
#define XBRAM_HW_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/** @name Registers
*
* Register offsets for this device.
* @{
*/
#define XBRAM_ECC_STATUS_OFFSET 0x0 /**< ECC status Register */
#define XBRAM_ECC_EN_IRQ_OFFSET 0x4 /**< ECC interrupt enable Register */
#define XBRAM_ECC_ON_OFF_OFFSET 0x8 /**< ECC on/off register */
#define XBRAM_CE_CNT_OFFSET 0xC /**< Correctable error counter Register */
#define XBRAM_CE_FFD_0_OFFSET 0x100 /**< Correctable error first failing
* data Register, 31-0 */
#define XBRAM_CE_FFD_1_OFFSET 0x104 /**< Correctable error first failing
* data Register, 63-32 */
#define XBRAM_CE_FFD_2_OFFSET 0x108 /**< Correctable error first failing
* data Register, 95-64 */
#define XBRAM_CE_FFD_3_OFFSET 0x10C /**< Correctable error first failing
* data Register, 127-96 */
#define XBRAM_CE_FFD_4_OFFSET 0x110 /**< Correctable error first failing
* data Register, 159-128 */
#define XBRAM_CE_FFD_5_OFFSET 0x114 /**< Correctable error first failing
* data Register, 191-160 */
#define XBRAM_CE_FFD_6_OFFSET 0x118 /**< Correctable error first failing
* data Register, 223-192 */
#define XBRAM_CE_FFD_7_OFFSET 0x11C /**< Correctable error first failing
* data Register, 255-224 */
#define XBRAM_CE_FFD_8_OFFSET 0x120 /**< Correctable error first failing
* data Register, 287-256 */
#define XBRAM_CE_FFD_9_OFFSET 0x124 /**< Correctable error first failing
* data Register, 319-288 */
#define XBRAM_CE_FFD_10_OFFSET 0x128 /**< Correctable error first failing
* data Register, 351-320 */
#define XBRAM_CE_FFD_11_OFFSET 0x12C /**< Correctable error first failing
* data Register, 383-352 */
#define XBRAM_CE_FFD_12_OFFSET 0x130 /**< Correctable error first failing
* data Register, 415-384 */
#define XBRAM_CE_FFD_13_OFFSET 0x134 /**< Correctable error first failing
* data Register, 447-416 */
#define XBRAM_CE_FFD_14_OFFSET 0x138 /**< Correctable error first failing
* data Register, 479-448 */
#define XBRAM_CE_FFD_15_OFFSET 0x13C /**< Correctable error first failing
* data Register, 511-480 */
#define XBRAM_CE_FFD_16_OFFSET 0x140 /**< Correctable error first failing
* data Register, 543-512 */
#define XBRAM_CE_FFD_17_OFFSET 0x144 /**< Correctable error first failing
* data Register, 575-544 */
#define XBRAM_CE_FFD_18_OFFSET 0x148 /**< Correctable error first failing
* data Register, 607-576 */
#define XBRAM_CE_FFD_19_OFFSET 0x14C /**< Correctable error first failing
* data Register, 639-608 */
#define XBRAM_CE_FFD_20_OFFSET 0x150 /**< Correctable error first failing
* data Register, 671-640 */
#define XBRAM_CE_FFD_21_OFFSET 0x154 /**< Correctable error first failing
* data Register, 703-672 */
#define XBRAM_CE_FFD_22_OFFSET 0x158 /**< Correctable error first failing
* data Register, 735-704 */
#define XBRAM_CE_FFD_23_OFFSET 0x15C /**< Correctable error first failing
* data Register, 767-736 */
#define XBRAM_CE_FFD_24_OFFSET 0x160 /**< Correctable error first failing
* data Register, 799-768 */
#define XBRAM_CE_FFD_25_OFFSET 0x164 /**< Correctable error first failing
* data Register, 831-800 */
#define XBRAM_CE_FFD_26_OFFSET 0x168 /**< Correctable error first failing
* data Register, 863-832 */
#define XBRAM_CE_FFD_27_OFFSET 0x16C /**< Correctable error first failing
* data Register, 895-864 */
#define XBRAM_CE_FFD_28_OFFSET 0x170 /**< Correctable error first failing
* data Register, 927-896 */
#define XBRAM_CE_FFD_29_OFFSET 0x174 /**< Correctable error first failing
* data Register, 959-928 */
#define XBRAM_CE_FFD_30_OFFSET 0x178 /**< Correctable error first failing
* data Register, 991-960 */
#define XBRAM_CE_FFD_31_OFFSET 0x17C /**< Correctable error first failing
* data Register, 1023-992 */
#define XBRAM_CE_FFE_0_OFFSET 0x180 /**< Correctable error first failing
* ECC Register, 31-0 */
#define XBRAM_CE_FFE_1_OFFSET 0x184 /**< Correctable error first failing
* ECC Register, 63-32 */
#define XBRAM_CE_FFE_2_OFFSET 0x188 /**< Correctable error first failing
* ECC Register, 95-64 */
#define XBRAM_CE_FFE_3_OFFSET 0x18C /**< Correctable error first failing
* ECC Register, 127-96 */
#define XBRAM_CE_FFE_4_OFFSET 0x190 /**< Correctable error first failing
* ECC Register, 159-128 */
#define XBRAM_CE_FFE_5_OFFSET 0x194 /**< Correctable error first failing
* ECC Register, 191-160 */
#define XBRAM_CE_FFE_6_OFFSET 0x198 /**< Correctable error first failing
* ECC Register, 223-192 */
#define XBRAM_CE_FFE_7_OFFSET 0x19C /**< Correctable error first failing
* ECC Register, 255-224 */
#define XBRAM_CE_FFA_0_OFFSET 0x1C0 /**< Correctable error first failing
* address Register 31-0 */
#define XBRAM_CE_FFA_1_OFFSET 0x1C4 /**< Correctable error first failing
* address Register 63-32 */
#define XBRAM_UE_FFD_0_OFFSET 0x200 /**< Uncorrectable error first failing
* data Register, 31-0 */
#define XBRAM_UE_FFD_1_OFFSET 0x204 /**< Uncorrectable error first failing
* data Register, 63-32 */
#define XBRAM_UE_FFD_2_OFFSET 0x208 /**< Uncorrectable error first failing
* data Register, 95-64 */
#define XBRAM_UE_FFD_3_OFFSET 0x20C /**< Uncorrectable error first failing
* data Register, 127-96 */
#define XBRAM_UE_FFD_4_OFFSET 0x210 /**< Uncorrectable error first failing
* data Register, 159-128 */
#define XBRAM_UE_FFD_5_OFFSET 0x214 /**< Uncorrectable error first failing
* data Register, 191-160 */
#define XBRAM_UE_FFD_6_OFFSET 0x218 /**< Uncorrectable error first failing
* data Register, 223-192 */
#define XBRAM_UE_FFD_7_OFFSET 0x21C /**< Uncorrectable error first failing
* data Register, 255-224 */
#define XBRAM_UE_FFD_8_OFFSET 0x220 /**< Uncorrectable error first failing
* data Register, 287-256 */
#define XBRAM_UE_FFD_9_OFFSET 0x224 /**< Uncorrectable error first failing
* data Register, 319-288 */
#define XBRAM_UE_FFD_10_OFFSET 0x228 /**< Uncorrectable error first failing
* data Register, 351-320 */
#define XBRAM_UE_FFD_11_OFFSET 0x22C /**< Uncorrectable error first failing
* data Register, 383-352 */
#define XBRAM_UE_FFD_12_OFFSET 0x230 /**< Uncorrectable error first failing
* data Register, 415-384 */
#define XBRAM_UE_FFD_13_OFFSET 0x234 /**< Uncorrectable error first failing
* data Register, 447-416 */
#define XBRAM_UE_FFD_14_OFFSET 0x238 /**< Uncorrectable error first failing
* data Register, 479-448 */
#define XBRAM_UE_FFD_15_OFFSET 0x23C /**< Uncorrectable error first failing
* data Register, 511-480 */
#define XBRAM_UE_FFD_16_OFFSET 0x240 /**< Uncorrectable error first failing
* data Register, 543-512 */
#define XBRAM_UE_FFD_17_OFFSET 0x244 /**< Uncorrectable error first failing
* data Register, 575-544 */
#define XBRAM_UE_FFD_18_OFFSET 0x248 /**< Uncorrectable error first failing
* data Register, 607-576 */
#define XBRAM_UE_FFD_19_OFFSET 0x24C /**< Uncorrectable error first failing
* data Register, 639-608 */
#define XBRAM_UE_FFD_20_OFFSET 0x250 /**< Uncorrectable error first failing
* data Register, 671-640 */
#define XBRAM_UE_FFD_21_OFFSET 0x254 /**< Uncorrectable error first failing
* data Register, 703-672 */
#define XBRAM_UE_FFD_22_OFFSET 0x258 /**< Uncorrectable error first failing
* data Register, 735-704 */
#define XBRAM_UE_FFD_23_OFFSET 0x25C /**< Uncorrectable error first failing
* data Register, 767-736 */
#define XBRAM_UE_FFD_24_OFFSET 0x260 /**< Uncorrectable error first failing
* data Register, 799-768 */
#define XBRAM_UE_FFD_25_OFFSET 0x264 /**< Uncorrectable error first failing
* data Register, 831-800 */
#define XBRAM_UE_FFD_26_OFFSET 0x268 /**< Uncorrectable error first failing
* data Register, 863-832 */
#define XBRAM_UE_FFD_27_OFFSET 0x26C /**< Uncorrectable error first failing
* data Register, 895-864 */
#define XBRAM_UE_FFD_28_OFFSET 0x270 /**< Uncorrectable error first failing
* data Register, 927-896 */
#define XBRAM_UE_FFD_29_OFFSET 0x274 /**< Uncorrectable error first failing
* data Register, 959-928 */
#define XBRAM_UE_FFD_30_OFFSET 0x278 /**< Uncorrectable error first failing
* data Register, 991-960 */
#define XBRAM_UE_FFD_31_OFFSET 0x27C /**< Uncorrectable error first failing
* data Register, 1023-992 */
#define XBRAM_UE_FFE_0_OFFSET 0x280 /**< Uncorrectable error first failing
* ECC Register, 31-0 */
#define XBRAM_UE_FFE_1_OFFSET 0x284 /**< Uncorrectable error first failing
* ECC Register, 63-32 */
#define XBRAM_UE_FFE_2_OFFSET 0x288 /**< Uncorrectable error first failing
* ECC Register, 95-64 */
#define XBRAM_UE_FFE_3_OFFSET 0x28C /**< Uncorrectable error first failing
* ECC Register, 127-96 */
#define XBRAM_UE_FFE_4_OFFSET 0x290 /**< Uncorrectable error first failing
* ECC Register, 159-128 */
#define XBRAM_UE_FFE_5_OFFSET 0x294 /**< Uncorrectable error first failing
* ECC Register, 191-160 */
#define XBRAM_UE_FFE_6_OFFSET 0x298 /**< Uncorrectable error first failing
* ECC Register, 223-192 */
#define XBRAM_UE_FFE_7_OFFSET 0x29C /**< Uncorrectable error first failing
* ECC Register, 255-224 */
#define XBRAM_UE_FFA_0_OFFSET 0x2C0 /**< Uncorrectable error first failing
* address Register 31-0 */
#define XBRAM_UE_FFA_1_OFFSET 0x2C4 /**< Uncorrectable error first failing
* address Register 63-32 */
#define XBRAM_FI_D_0_OFFSET 0x300 /**< Fault injection Data Register,
* 31-0 */
#define XBRAM_FI_D_1_OFFSET 0x304 /**< Fault injection Data Register,
* 63-32 */
#define XBRAM_FI_D_2_OFFSET 0x308 /**< Fault injection Data Register,
* 95-64 */
#define XBRAM_FI_D_3_OFFSET 0x30C /**< Fault injection Data Register,
* 127-96 */
#define XBRAM_FI_D_4_OFFSET 0x310 /**< Fault injection Data Register,
* 159-128 */
#define XBRAM_FI_D_5_OFFSET 0x314 /**< Fault injection Data Register,
* 191-160 */
#define XBRAM_FI_D_6_OFFSET 0x318 /**< Fault injection Data Register,
* 223-192 */
#define XBRAM_FI_D_7_OFFSET 0x31C /**< Fault injection Data Register,
* 255-224 */
#define XBRAM_FI_D_8_OFFSET 0x320 /**< Fault injection Data Register,
* 287-256 */
#define XBRAM_FI_D_9_OFFSET 0x324 /**< Fault injection Data Register,
* 319-288 */
#define XBRAM_FI_D_10_OFFSET 0x328 /**< Fault injection Data Register,
* 351-320 */
#define XBRAM_FI_D_11_OFFSET 0x32C /**< Fault injection Data Register,
* 383-352 */
#define XBRAM_FI_D_12_OFFSET 0x330 /**< Fault injection Data Register,
* 415-384 */
#define XBRAM_FI_D_13_OFFSET 0x334 /**< Fault injection Data Register,
* 447-416 */
#define XBRAM_FI_D_14_OFFSET 0x338 /**< Fault injection Data Register,
* 479-448 */
#define XBRAM_FI_D_15_OFFSET 0x33C /**< Fault injection Data Register,
* 511-480 */
#define XBRAM_FI_D_16_OFFSET 0x340 /**< Fault injection Data Register,
* 543-512 */
#define XBRAM_FI_D_17_OFFSET 0x344 /**< Fault injection Data Register,
* 575-544 */
#define XBRAM_FI_D_18_OFFSET 0x348 /**< Fault injection Data Register,
* 607-576 */
#define XBRAM_FI_D_19_OFFSET 0x34C /**< Fault injection Data Register,
* 639-608 */
#define XBRAM_FI_D_20_OFFSET 0x350 /**< Fault injection Data Register,
* 671-640 */
#define XBRAM_FI_D_21_OFFSET 0x354 /**< Fault injection Data Register,
* 703-672 */
#define XBRAM_FI_D_22_OFFSET 0x358 /**< Fault injection Data Register,
* 735-704 */
#define XBRAM_FI_D_23_OFFSET 0x35C /**< Fault injection Data Register,
* 767-736 */
#define XBRAM_FI_D_24_OFFSET 0x360 /**< Fault injection Data Register,
* 799-768 */
#define XBRAM_FI_D_25_OFFSET 0x364 /**< Fault injection Data Register,
* 831-800 */
#define XBRAM_FI_D_26_OFFSET 0x368 /**< Fault injection Data Register,
* 863-832 */
#define XBRAM_FI_D_27_OFFSET 0x36C /**< Fault injection Data Register,
* 895-864 */
#define XBRAM_FI_D_28_OFFSET 0x370 /**< Fault injection Data Register,
* 927-896 */
#define XBRAM_FI_D_29_OFFSET 0x374 /**< Fault injection Data Register,
* 959-928 */
#define XBRAM_FI_D_30_OFFSET 0x378 /**< Fault injection Data Register,
* 991-960 */
#define XBRAM_FI_D_31_OFFSET 0x37C /**< Fault injection Data Register,
* 1023-992 */
#define XBRAM_FI_ECC_0_OFFSET 0x380 /**< Fault injection ECC Register,
* 31-0 */
#define XBRAM_FI_ECC_1_OFFSET 0x384 /**< Fault injection ECC Register,
* 63-32 */
#define XBRAM_FI_ECC_2_OFFSET 0x388 /**< Fault injection ECC Register,
* 95-64 */
#define XBRAM_FI_ECC_3_OFFSET 0x38C /**< Fault injection ECC Register,
* 127-96 */
#define XBRAM_FI_ECC_4_OFFSET 0x390 /**< Fault injection ECC Register,
* 159-128 */
#define XBRAM_FI_ECC_5_OFFSET 0x394 /**< Fault injection ECC Register,
* 191-160 */
#define XBRAM_FI_ECC_6_OFFSET 0x398 /**< Fault injection ECC Register,
* 223-192 */
#define XBRAM_FI_ECC_7_OFFSET 0x39C /**< Fault injection ECC Register,
* 255-224 */
/* @} */
/** @name Interrupt Status and Enable Register bitmaps and masks
*
* Bit definitions for the ECC status register and ECC interrupt enable register.
* @{
*/
#define XBRAM_IR_CE_MASK 0x2 /**< Mask for the correctable error */
#define XBRAM_IR_UE_MASK 0x1 /**< Mask for the uncorrectable error */
#define XBRAM_IR_ALL_MASK 0x3 /**< Mask of all bits */
/*@}*/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define XBram_In32 Xil_In32
#define XBram_Out32 Xil_Out32
#define XBram_In16 Xil_In16
#define XBram_Out16 Xil_Out16
#define XBram_In8 Xil_In8
#define XBram_Out8 Xil_Out8
/****************************************************************************/
/**
*
* Write a value to a BRAM register. A 32 bit write is performed.
*
* @param BaseAddress is the base address of the BRAM device register.
* @param RegOffset 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 XBram_WriteReg(u32 BaseAddress, u32 RegOffset, u32 Data)
*
****************************************************************************/
#define XBram_WriteReg(BaseAddress, RegOffset, Data) \
XBram_Out32((BaseAddress) + (RegOffset), (u32)(Data))
/****************************************************************************/
/**
*
* Read a value from a BRAM register. A 32 bit read is performed.
*
* @param BaseAddress is the base address of the BRAM device registers.
* @param RegOffset is the register offset from the base to read from.
*
* @return Data read from the register.
*
* @note C-style signature:
* u32 XBram_ReadReg(u32 BaseAddress, u32 RegOffset)
*
****************************************************************************/
#define XBram_ReadReg(BaseAddress, RegOffset) \
XBram_In32((BaseAddress) + (RegOffset))
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */
@@ -1,74 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2015 - 2019 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcoresightpsdcc.h
* @addtogroup coresightps_dcc_v1_5
* @{
* @details
*
* CoreSight driver component.
*
* The coresight is a part of debug communication channel (DCC) group. Jtag UART
* for ARM uses DCC. Each ARM core has its own DCC, so one need to select an
* ARM target in XSDB console before running the jtag terminal command. Using the
* coresight driver component, the output stream can be directed to a log file.
*
* @note None.
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ----- -------- -----------------------------------------------
* 1.00 kvn 02/14/15 First release
* 1.1 kvn 06/12/15 Add support for Zynq Ultrascale+ MP.
* kvn 08/18/15 Modified Makefile according to compiler changes.
* 1.3 asa 07/01/16 Made changes to ensure that the file does not compile
* for MB BSPs. Instead it throws up a warning. This
* fixes the CR#953056.
* 1.5 sne 01/19/19 Fixed MISRA-C Violations CR#1025101.
*
* </pre>
*
******************************************************************************/
/***************************** Include Files *********************************/
#ifndef XCORESIGHTPSDCC_H /* prevent circular inclusions */
#define XCORESIGHTPSDCC_H /* by using protection macros */
#ifndef __MICROBLAZE__
#include <xil_types.h>
void XCoresightPs_DccSendByte(u32 BaseAddress, u8 Data);
u8 XCoresightPs_DccRecvByte(u32 BaseAddress);
#endif
#endif
/** @} */
@@ -1,47 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2011 - 2018 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcpu_cortexa9.h
* @addtogroup cpu_cortexa9_v2_7
* @{
* @details
*
* dummy file
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------------
* 2.5 ms 04/18/17 Modified tcl file to add suffix U for XPAR_CPU_ID
* parameter of cpu_cortexa9 in xparameters.h
# 2.7 mus 07/03/18 Updated tcl to not to add default flags forcefully into
# extra compiler flags. Now, user can remove default flags
# from extra compiler flags. It fixes CR#998768.
******************************************************************************/
/** @} */
@@ -1,62 +0,0 @@
/*******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
*******************************************************************************/
/******************************************************************************/
/**
*
* @file xddrps.h
* @addtogroup ddrps_v1_0
* @{
* @details
*
* The Xilinx DdrPs driver. This driver supports the Xilinx ddrps
* IP core.
*
* @note None.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.0 nsk 08/06/15 First Release
* 1.0 nsk 08/20/15 Updated define_addr_params in ddrps.tcl
* to support PBD Designs (CR #876857)
*
* </pre>
*
*******************************************************************************/
#ifndef XDDRPS_H_
/* Prevent circular inclusions by using protection macros. */
#define XDDRPS_H_
/******************************* Include Files ********************************/
#endif /* XDDRPS_H_ */
/** @} */
@@ -1,40 +0,0 @@
#ifndef XDEBUG /* prevent circular inclusions */
#define XDEBUG /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
#if defined(DEBUG) && !defined(NDEBUG)
#ifndef XDEBUG_WARNING
#define XDEBUG_WARNING
#warning DEBUG is enabled
#endif
int printf(const char *format, ...);
#define XDBG_DEBUG_ERROR 0x00000001U /* error condition messages */
#define XDBG_DEBUG_GENERAL 0x00000002U /* general debug messages */
#define XDBG_DEBUG_ALL 0xFFFFFFFFU /* all debugging data */
#define xdbg_current_types (XDBG_DEBUG_GENERAL)
#define xdbg_stmnt(x) x
#define xdbg_printf(type, ...) (((type) & xdbg_current_types) ? printf (__VA_ARGS__) : 0)
#else /* defined(DEBUG) && !defined(NDEBUG) */
#define xdbg_stmnt(x)
#define xdbg_printf(...)
#endif /* defined(DEBUG) && !defined(NDEBUG) */
#ifdef __cplusplus
}
#endif
#endif /* XDEBUG */
@@ -1,399 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2017 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xdevcfg.h
* @addtogroup devcfg_v3_5
* @{
* @details
*
* The is the main header file for the Device Configuration Interface of the Zynq
* device. The device configuration interface has three main functionality.
* 1. AXI-PCAP
* 2. Security Policy
* 3. XADC
* This current version of the driver supports only the AXI-PCAP and Security
* Policy blocks. There is a separate driver for XADC.
*
* AXI-PCAP is used for download/upload an encrypted or decrypted bitstream.
* DMA embedded in the AXI PCAP provides the master interface to
* the Device configuration block for any DMA transfers. The data transfer can
* take place between the Tx/RxFIFOs of AXI-PCAP and memory (on chip
* RAM/DDR/peripheral memory).
*
* The current driver only supports the downloading the FPGA bitstream and
* readback of the decrypted image (sort of loopback).
* The driver does not know what information needs to be written to the FPGA to
* readback FPGA configuration register or memory data. The application above the
* driver should take care of creating the data that needs to be downloaded to
* the FPGA so that the bitstream can be readback.
* This driver also does not support the reading of the internal registers of the
* PCAP. The driver has no knowledge of the PCAP internals.
*
* <b> Initialization and Configuration </b>
*
* The device driver enables higher layer software (e.g., an application) to
* communicate with the Device Configuration device.
*
* XDcfg_CfgInitialize() API is used to initialize the Device Configuration
* Interface. The user needs to first call the XDcfg_LookupConfig() API which
* returns the Configuration structure pointer which is passed as a parameter to
* the XDcfg_CfgInitialize() API.
*
* <b>Interrupts</b>
* The Driver implements an interrupt handler to support the interrupts provided
* by this interface.
*
* <b> Threads </b>
*
* This driver is not thread safe. Any needs for threads or thread mutual
* exclusion must be satisfied by the layer above this driver.
*
* <b> Asserts </b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on argument
* values. Asserts can be turned off on a system-wide basis by defining, at
* compile time, the NDEBUG identifier. By default, asserts are turned on and it
* is recommended that users leave asserts on during development.
*
* <b> Building the driver </b>
*
* The XDcfg driver is composed of several source files. This allows the user
* to build and link only those parts of the driver that are necessary.
*
* <br><br>
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- ---------------------------------------------
* 1.00a hvm 02/07/11 First release
* 2.00a nm 05/31/12 Updated the driver for CR 660835 so that input length for
* source/destination to the XDcfg_InitiateDma, XDcfg_Transfer
* APIs is words (32 bit) and not bytes.
* Updated the notes for XDcfg_InitiateDma/XDcfg_Transfer APIs
* to add information that 2 LSBs of the Source/Destination
* address when equal to 2�b01 indicate the last DMA command
* of an overall transfer.
* Destination Address passed to this API for secure transfers
* instead of using 0xFFFFFFFF for CR 662197. This issue was
* resulting in the failure of secure transfers of
* non-bitstream images.
* 2.01a nm 07/07/12 Updated the XDcfg_IntrClear function to directly
* set the mask instead of oring it with the
* value read from the interrupt status register
* Added defines for the PS Version bits,
* removed the FIFO Flush bits from the
* Miscellaneous Control Reg.
* Added XDcfg_GetPsVersion, XDcfg_SelectIcapInterface
* and XDcfg_SelectPcapInterface APIs for CR 643295
* The user has to call the XDcfg_SelectIcapInterface API
* for the PL reconfiguration using AXI HwIcap.
* Updated the XDcfg_Transfer API to clear the
* QUARTER_PCAP_RATE_EN bit in the control register for
* non secure writes for CR 675543.
* 2.02a nm 01/31/13 Fixed CR# 679335.
* Added Setting and Clearing the internal PCAP loopback.
* Removed code for enabling/disabling AES engine as BootROM
* locks down this setting.
* Fixed CR# 681976.
* Skip Checking the PCFG_INIT in case of non-secure DMA
* loopback.
* Fixed CR# 699558.
* XDcfg_Transfer fails to transfer data in loopback mode.
* Fixed CR# 701348.
* Peripheral test fails with Running
* DcfgSelfTestExample() in SECURE bootmode.
* 2.03a nm 04/19/13 Fixed CR# 703728.
* Updated the register definitions as per the latest TRM
* version UG585 (v1.4) November 16, 2012.
* 3.0 adk 10/12/13 Updated as per the New Tcl API's
* 3.0 kpc 21/02/14 Added function prototype for XDcfg_ClearControlRegister
* 3.2 sb 08/25/14 Fixed XDcfg_PcapReadback() function
* updated driver code with != instead of ==,
* while checking for Interrupt Status with DMA and
* PCAP Done Mask
* ((XDcfg_ReadReg(InstancePtr->Config.BaseAddr,
* XDCFG_INT_STS_OFFSET) &
* XDCFG_IXR_D_P_DONE_MASK) !=
* XDCFG_IXR_D_P_DONE_MASK);
* A new example has been added to read back the
* configuration registers from the PL region.
* xdevcfg_reg_readback_example.c
* 3.3 sk 04/06/15 Modified XDcfg_ReadMultiBootConfig Macro CR# 851335.
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
* generation.
* ms 04/10/17 Modified filename tag in interrupt and polled examples
* to include them in doxygen examples.
* 3.5 ms 04/18/17 Modified tcl file to add suffix U for all macros
* definitions of devcfg in xparameters.h
* ms 08/07/17 Fixed compilation warnings in xdevcfg_sinit.c
* </pre>
*
******************************************************************************/
#ifndef XDCFG_H /* prevent circular inclusions */
#define XDCFG_H /* by using protection macros */
/***************************** Include Files *********************************/
#include "xdevcfg_hw.h"
#include "xstatus.h"
#include "xil_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/************************** Constant Definitions *****************************/
/* Types of PCAP transfers */
#define XDCFG_NON_SECURE_PCAP_WRITE 1
#define XDCFG_SECURE_PCAP_WRITE 2
#define XDCFG_PCAP_READBACK 3
#define XDCFG_CONCURRENT_SECURE_READ_WRITE 4
#define XDCFG_CONCURRENT_NONSEC_READ_WRITE 5
/**************************** Type Definitions *******************************/
/**
* The handler data type allows the user to define a callback function to
* respond to interrupt events in the system. This function is executed
* in interrupt context, so amount of processing should be minimized.
*
* @param CallBackRef is the callback reference passed in by the upper
* layer when setting the callback functions, and passed back to
* the upper layer when the callback is invoked. Its type is
* unimportant to the driver component, so it is a void pointer.
* @param Status is the Interrupt status of the XDcfg device.
*/
typedef void (*XDcfg_IntrHandler) (void *CallBackRef, u32 Status);
/**
* This typedef contains configuration information for the device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddr; /**< Base address of the device */
} XDcfg_Config;
/**
* The XDcfg driver instance data.
*/
typedef struct {
XDcfg_Config Config; /**< Hardware Configuration */
u32 IsReady; /**< Device is initialized and ready */
u32 IsStarted; /**< Device Configuration Interface
* is running
*/
XDcfg_IntrHandler StatusHandler; /* Event handler function */
void *CallBackRef; /* Callback reference for event handler */
} XDcfg;
/****************************************************************************/
/**
*
* Unlock the Device Config Interface block.
*
* @param InstancePtr is a pointer to the instance of XDcfg driver.
*
* @return None.
*
* @note C-style signature:
* void XDcfg_Unlock(XDcfg* InstancePtr)
*
*****************************************************************************/
#define XDcfg_Unlock(InstancePtr) \
XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, \
XDCFG_UNLOCK_OFFSET, XDCFG_UNLOCK_DATA)
/****************************************************************************/
/**
*
* Get the version number of the PS from the Miscellaneous Control Register.
*
* @param InstancePtr is a pointer to the instance of XDcfg driver.
*
* @return Version of the PS.
*
* @note C-style signature:
* void XDcfg_GetPsVersion(XDcfg* InstancePtr)
*
*****************************************************************************/
#define XDcfg_GetPsVersion(InstancePtr) \
((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, \
XDCFG_MCTRL_OFFSET)) & \
XDCFG_MCTRL_PCAP_PS_VERSION_MASK) >> \
XDCFG_MCTRL_PCAP_PS_VERSION_SHIFT
/****************************************************************************/
/**
*
* Read the multiboot config register value.
*
* @param InstancePtr is a pointer to the instance of XDcfg driver.
*
* @return None.
*
* @note C-style signature:
* u32 XDcfg_ReadMultiBootConfig(XDcfg* InstancePtr)
*
*****************************************************************************/
#define XDcfg_ReadMultiBootConfig(InstancePtr) \
XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, \
XDCFG_MULTIBOOT_ADDR_OFFSET)
/****************************************************************************/
/**
*
* Selects ICAP interface for reconfiguration after the initial configuration
* of the PL.
*
* @param InstancePtr is a pointer to the instance of XDcfg driver.
*
* @return None.
*
* @note C-style signature:
* void XDcfg_SelectIcapInterface(XDcfg* InstancePtr)
*
*****************************************************************************/
#define XDcfg_SelectIcapInterface(InstancePtr) \
XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET, \
((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \
& ( ~XDCFG_CTRL_PCAP_PR_MASK)))
/****************************************************************************/
/**
*
* Selects PCAP interface for reconfiguration after the initial configuration
* of the PL.
*
* @param InstancePtr is a pointer to the instance of XDcfg driver.
*
* @return None.
*
* @note C-style signature:
* void XDcfg_SelectPcapInterface(XDcfg* InstancePtr)
*
*****************************************************************************/
#define XDcfg_SelectPcapInterface(InstancePtr) \
XDcfg_WriteReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET, \
((XDcfg_ReadReg((InstancePtr)->Config.BaseAddr, XDCFG_CTRL_OFFSET)) \
| XDCFG_CTRL_PCAP_PR_MASK))
/************************** Function Prototypes ******************************/
/*
* Lookup configuration in xdevcfg_sinit.c.
*/
XDcfg_Config *XDcfg_LookupConfig(u16 DeviceId);
/*
* Selftest function in xdevcfg_selftest.c
*/
int XDcfg_SelfTest(XDcfg *InstancePtr);
/*
* Interface functions in xdevcfg.c
*/
int XDcfg_CfgInitialize(XDcfg *InstancePtr,
XDcfg_Config *ConfigPtr, u32 EffectiveAddress);
void XDcfg_EnablePCAP(XDcfg *InstancePtr);
void XDcfg_DisablePCAP(XDcfg *InstancePtr);
void XDcfg_SetControlRegister(XDcfg *InstancePtr, u32 Mask);
void XDcfg_ClearControlRegister(XDcfg *InstancePtr, u32 Mask);
u32 XDcfg_GetControlRegister(XDcfg *InstancePtr);
void XDcfg_SetLockRegister(XDcfg *InstancePtr, u32 Data);
u32 XDcfg_GetLockRegister(XDcfg *InstancePtr);
void XDcfg_SetConfigRegister(XDcfg *InstancePtr, u32 Data);
u32 XDcfg_GetConfigRegister(XDcfg *InstancePtr);
void XDcfg_SetStatusRegister(XDcfg *InstancePtr, u32 Data);
u32 XDcfg_GetStatusRegister(XDcfg *InstancePtr);
void XDcfg_SetRomShadowRegister(XDcfg *InstancePtr, u32 Data);
u32 XDcfg_GetSoftwareIdRegister(XDcfg *InstancePtr);
void XDcfg_SetMiscControlRegister(XDcfg *InstancePtr, u32 Mask);
u32 XDcfg_GetMiscControlRegister(XDcfg *InstancePtr);
u32 XDcfg_IsDmaBusy(XDcfg *InstancePtr);
void XDcfg_InitiateDma(XDcfg *InstancePtr, u32 SourcePtr, u32 DestPtr,
u32 SrcWordLength, u32 DestWordLength);
u32 XDcfg_Transfer(XDcfg *InstancePtr,
void *SourcePtr, u32 SrcWordLength,
void *DestPtr, u32 DestWordLength,
u32 TransferType);
/*
* Interrupt related function prototypes implemented in xdevcfg_intr.c
*/
void XDcfg_IntrEnable(XDcfg *InstancePtr, u32 Mask);
void XDcfg_IntrDisable(XDcfg *InstancePtr, u32 Mask);
u32 XDcfg_IntrGetEnabled(XDcfg *InstancePtr);
u32 XDcfg_IntrGetStatus(XDcfg *InstancePtr);
void XDcfg_IntrClear(XDcfg *InstancePtr, u32 Mask);
void XDcfg_InterruptHandler(XDcfg *InstancePtr);
void XDcfg_SetHandler(XDcfg *InstancePtr, void *CallBackFunc,
void *CallBackRef);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */
@@ -1,391 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xdevcfg_hw.h
* @addtogroup devcfg_v3_3
* @{
*
* This file contains the hardware interface to the Device Config Interface.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- --- -------- ---------------------------------------------
* 1.00a hvm 02/07/11 First release
* 2.01a nm 08/01/12 Added defines for the PS Version bits,
* removed the FIFO Flush bits from the
* Miscellaneous Control Reg
* 2.03a nm 04/19/13 Fixed CR# 703728.
* Updated the register definitions as per the latest TRM
* version UG585 (v1.4) November 16, 2012.
* 2.04a kpc 10/07/13 Added function prototype.
* 3.00a kpc 25/02/14 Corrected the XDCFG_BASE_ADDRESS macro value.
* </pre>
*
******************************************************************************/
#ifndef XDCFG_HW_H /* prevent circular inclusions */
#define XDCFG_HW_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/** @name Register Map
* Offsets of registers from the start of the device
* @{
*/
#define XDCFG_CTRL_OFFSET 0x00 /**< Control Register */
#define XDCFG_LOCK_OFFSET 0x04 /**< Lock Register */
#define XDCFG_CFG_OFFSET 0x08 /**< Configuration Register */
#define XDCFG_INT_STS_OFFSET 0x0C /**< Interrupt Status Register */
#define XDCFG_INT_MASK_OFFSET 0x10 /**< Interrupt Mask Register */
#define XDCFG_STATUS_OFFSET 0x14 /**< Status Register */
#define XDCFG_DMA_SRC_ADDR_OFFSET 0x18 /**< DMA Source Address Register */
#define XDCFG_DMA_DEST_ADDR_OFFSET 0x1C /**< DMA Destination Address Reg */
#define XDCFG_DMA_SRC_LEN_OFFSET 0x20 /**< DMA Source Transfer Length */
#define XDCFG_DMA_DEST_LEN_OFFSET 0x24 /**< DMA Destination Transfer */
#define XDCFG_ROM_SHADOW_OFFSET 0x28 /**< DMA ROM Shadow Register */
#define XDCFG_MULTIBOOT_ADDR_OFFSET 0x2C /**< Multi BootAddress Pointer */
#define XDCFG_SW_ID_OFFSET 0x30 /**< Software ID Register */
#define XDCFG_UNLOCK_OFFSET 0x34 /**< Unlock Register */
#define XDCFG_MCTRL_OFFSET 0x80 /**< Miscellaneous Control Reg */
/* @} */
/** @name Control Register Bit definitions
* @{
*/
#define XDCFG_CTRL_FORCE_RST_MASK 0x80000000 /**< Force into
* Secure Reset
*/
#define XDCFG_CTRL_PCFG_PROG_B_MASK 0x40000000 /**< Program signal to
* Reset FPGA
*/
#define XDCFG_CTRL_PCFG_POR_CNT_4K_MASK 0x20000000 /**< Control PL POR timer */
#define XDCFG_CTRL_PCAP_PR_MASK 0x08000000 /**< Enable PCAP for PR */
#define XDCFG_CTRL_PCAP_MODE_MASK 0x04000000 /**< Enable PCAP */
#define XDCFG_CTRL_PCAP_RATE_EN_MASK 0x02000000 /**< Enable PCAP send data
* to FPGA every 4 PCAP
* cycles
*/
#define XDCFG_CTRL_MULTIBOOT_EN_MASK 0x01000000 /**< Multiboot Enable */
#define XDCFG_CTRL_JTAG_CHAIN_DIS_MASK 0x00800000 /**< JTAG Chain Disable */
#define XDCFG_CTRL_USER_MODE_MASK 0x00008000 /**< User Mode Mask */
#define XDCFG_CTRL_PCFG_AES_FUSE_MASK 0x00001000 /**< AES key source */
#define XDCFG_CTRL_PCFG_AES_EN_MASK 0x00000E00 /**< AES Enable Mask */
#define XDCFG_CTRL_SEU_EN_MASK 0x00000100 /**< SEU Enable Mask */
#define XDCFG_CTRL_SEC_EN_MASK 0x00000080 /**< Secure/Non Secure
* Status mask
*/
#define XDCFG_CTRL_SPNIDEN_MASK 0x00000040 /**< Secure Non Invasive
* Debug Enable
*/
#define XDCFG_CTRL_SPIDEN_MASK 0x00000020 /**< Secure Invasive
* Debug Enable
*/
#define XDCFG_CTRL_NIDEN_MASK 0x00000010 /**< Non-Invasive Debug
* Enable
*/
#define XDCFG_CTRL_DBGEN_MASK 0x00000008 /**< Invasive Debug
* Enable
*/
#define XDCFG_CTRL_DAP_EN_MASK 0x00000007 /**< DAP Enable Mask */
/* @} */
/** @name Lock register bit definitions
* @{
*/
#define XDCFG_LOCK_AES_EFUSE_MASK 0x00000010 /**< Lock AES Efuse bit */
#define XDCFG_LOCK_AES_EN_MASK 0x00000008 /**< Lock AES_EN update */
#define XDCFG_LOCK_SEU_MASK 0x00000004 /**< Lock SEU_En update */
#define XDCFG_LOCK_SEC_MASK 0x00000002 /**< Lock SEC_EN and
* USER_MODE
*/
#define XDCFG_LOCK_DBG_MASK 0x00000001 /**< This bit locks
* security config
* including: DAP_En,
* DBGEN,,
* NIDEN, SPNIEN
*/
/*@}*/
/** @name Config Register Bit definitions
* @{
*/
#define XDCFG_CFG_RFIFO_TH_MASK 0x00000C00 /**< Read FIFO
* Threshold Mask
*/
#define XDCFG_CFG_WFIFO_TH_MASK 0x00000300 /**< Write FIFO Threshold
* Mask
*/
#define XDCFG_CFG_RCLK_EDGE_MASK 0x00000080 /**< Read data active
* clock edge
*/
#define XDCFG_CFG_WCLK_EDGE_MASK 0x00000040 /**< Write data active
* clock edge
*/
#define XDCFG_CFG_DISABLE_SRC_INC_MASK 0x00000020 /**< Disable Source address
* increment mask
*/
#define XDCFG_CFG_DISABLE_DST_INC_MASK 0x00000010 /**< Disable Destination
* address increment
* mask
*/
/* @} */
/** @name Interrupt Status/Mask Register Bit definitions
* @{
*/
#define XDCFG_IXR_PSS_GTS_USR_B_MASK 0x80000000 /**< Tri-state IO during
* HIZ
*/
#define XDCFG_IXR_PSS_FST_CFG_B_MASK 0x40000000 /**< First configuration
* done
*/
#define XDCFG_IXR_PSS_GPWRDWN_B_MASK 0x20000000 /**< Global power down */
#define XDCFG_IXR_PSS_GTS_CFG_B_MASK 0x10000000 /**< Tri-state IO during
* configuration
*/
#define XDCFG_IXR_PSS_CFG_RESET_B_MASK 0x08000000 /**< PL configuration
* reset
*/
#define XDCFG_IXR_AXI_WTO_MASK 0x00800000 /**< AXI Write Address
* or Data or response
* timeout
*/
#define XDCFG_IXR_AXI_WERR_MASK 0x00400000 /**< AXI Write response
* error
*/
#define XDCFG_IXR_AXI_RTO_MASK 0x00200000 /**< AXI Read Address or
* response timeout
*/
#define XDCFG_IXR_AXI_RERR_MASK 0x00100000 /**< AXI Read response
* error
*/
#define XDCFG_IXR_RX_FIFO_OV_MASK 0x00040000 /**< Rx FIFO Overflow */
#define XDCFG_IXR_WR_FIFO_LVL_MASK 0x00020000 /**< Tx FIFO less than
* threshold */
#define XDCFG_IXR_RD_FIFO_LVL_MASK 0x00010000 /**< Rx FIFO greater than
* threshold */
#define XDCFG_IXR_DMA_CMD_ERR_MASK 0x00008000 /**< Illegal DMA command */
#define XDCFG_IXR_DMA_Q_OV_MASK 0x00004000 /**< DMA command queue
* overflow
*/
#define XDCFG_IXR_DMA_DONE_MASK 0x00002000 /**< DMA Command Done */
#define XDCFG_IXR_D_P_DONE_MASK 0x00001000 /**< DMA and PCAP
* transfers Done
*/
#define XDCFG_IXR_P2D_LEN_ERR_MASK 0x00000800 /**< PCAP to DMA transfer
* length error
*/
#define XDCFG_IXR_PCFG_HMAC_ERR_MASK 0x00000040 /**< HMAC error mask */
#define XDCFG_IXR_PCFG_SEU_ERR_MASK 0x00000020 /**< SEU Error mask */
#define XDCFG_IXR_PCFG_POR_B_MASK 0x00000010 /**< FPGA POR mask */
#define XDCFG_IXR_PCFG_CFG_RST_MASK 0x00000008 /**< FPGA Reset mask */
#define XDCFG_IXR_PCFG_DONE_MASK 0x00000004 /**< Done Signal Mask */
#define XDCFG_IXR_PCFG_INIT_PE_MASK 0x00000002 /**< Detect Positive edge
* of Init Signal
*/
#define XDCFG_IXR_PCFG_INIT_NE_MASK 0x00000001 /**< Detect Negative edge
* of Init Signal
*/
#define XDCFG_IXR_ERROR_FLAGS_MASK (XDCFG_IXR_AXI_WTO_MASK | \
XDCFG_IXR_AXI_WERR_MASK | \
XDCFG_IXR_AXI_RTO_MASK | \
XDCFG_IXR_AXI_RERR_MASK | \
XDCFG_IXR_RX_FIFO_OV_MASK | \
XDCFG_IXR_DMA_CMD_ERR_MASK |\
XDCFG_IXR_DMA_Q_OV_MASK | \
XDCFG_IXR_P2D_LEN_ERR_MASK |\
XDCFG_IXR_PCFG_HMAC_ERR_MASK)
#define XDCFG_IXR_ALL_MASK 0x00F7F8EF
/* @} */
/** @name Status Register Bit definitions
* @{
*/
#define XDCFG_STATUS_DMA_CMD_Q_F_MASK 0x80000000 /**< DMA command
* Queue full
*/
#define XDCFG_STATUS_DMA_CMD_Q_E_MASK 0x40000000 /**< DMA command
* Queue empty
*/
#define XDCFG_STATUS_DMA_DONE_CNT_MASK 0x30000000 /**< Number of
* completed DMA
* transfers
*/
#define XDCFG_STATUS_RX_FIFO_LVL_MASK 0x01F000000 /**< Rx FIFO level */
#define XDCFG_STATUS_TX_FIFO_LVL_MASK 0x0007F000 /**< Tx FIFO level */
#define XDCFG_STATUS_PSS_GTS_USR_B 0x00000800 /**< Tri-state IO
* during HIZ
*/
#define XDCFG_STATUS_PSS_FST_CFG_B 0x00000400 /**< First PL config
* done
*/
#define XDCFG_STATUS_PSS_GPWRDWN_B 0x00000200 /**< Global power down */
#define XDCFG_STATUS_PSS_GTS_CFG_B 0x00000100 /**< Tri-state IO during
* config
*/
#define XDCFG_STATUS_SECURE_RST_MASK 0x00000080 /**< Secure Reset
* POR Status
*/
#define XDCFG_STATUS_ILLEGAL_APB_ACCESS_MASK 0x00000040 /**< Illegal APB
* access
*/
#define XDCFG_STATUS_PSS_CFG_RESET_B 0x00000020 /**< PL config
* reset status
*/
#define XDCFG_STATUS_PCFG_INIT_MASK 0x00000010 /**< FPGA Init
* Status
*/
#define XDCFG_STATUS_EFUSE_BBRAM_KEY_DISABLE_MASK 0x00000008
/**< BBRAM key
* disable
*/
#define XDCFG_STATUS_EFUSE_SEC_EN_MASK 0x00000004 /**< Efuse Security
* Enable Status
*/
#define XDCFG_STATUS_EFUSE_JTAG_DIS_MASK 0x00000002 /**< EFuse JTAG
* Disable
* status
*/
/* @} */
/** @name DMA Source/Destination Transfer Length Register Bit definitions
* @{
*/
#define XDCFG_DMA_LEN_MASK 0x7FFFFFF /**< Length Mask */
/*@}*/
/** @name Miscellaneous Control Register Bit definitions
* @{
*/
#define XDCFG_MCTRL_PCAP_PS_VERSION_MASK 0xF0000000 /**< PS Version Mask */
#define XDCFG_MCTRL_PCAP_PS_VERSION_SHIFT 28 /**< PS Version Shift */
#define XDCFG_MCTRL_PCAP_LPBK_MASK 0x00000010 /**< PCAP loopback mask */
/* @} */
/** @name FIFO Threshold Bit definitions
* @{
*/
#define XDCFG_CFG_FIFO_QUARTER 0x0 /**< Quarter empty */
#define XDCFG_CFG_FIFO_HALF 0x1 /**< Half empty */
#define XDCFG_CFG_FIFO_3QUARTER 0x2 /**< 3/4 empty */
#define XDCFG_CFG_FIFO_EMPTY 0x4 /**< Empty */
/* @}*/
/* Miscellaneous constant values */
#define XDCFG_DMA_INVALID_ADDRESS 0xFFFFFFFF /**< Invalid DMA address */
#define XDCFG_UNLOCK_DATA 0x757BDF0D /**< First APB access data*/
#define XDCFG_BASE_ADDRESS 0xF8007000 /**< Device Config base
* address
*/
#define XDCFG_CONFIG_RESET_VALUE 0x508 /**< Config reg reset value */
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/**
*
* Read the given register.
*
* @param BaseAddr is the base address of the device
* @param RegOffset is the register offset to be read
*
* @return The 32-bit value of the register
*
* @note C-style signature:
* u32 XDcfg_ReadReg(u32 BaseAddr, u32 RegOffset)
*
*****************************************************************************/
#define XDcfg_ReadReg(BaseAddr, RegOffset) \
Xil_In32((BaseAddr) + (RegOffset))
/****************************************************************************/
/**
*
* Write to the given register.
*
* @param BaseAddr is the base address of the device
* @param RegOffset is the register offset to be written
* @param Data is the 32-bit value to write to the register
*
* @return None.
*
* @note C-style signature:
* void XDcfg_WriteReg(u32 BaseAddr, u32 RegOffset, u32 Data)
*
*****************************************************************************/
#define XDcfg_WriteReg(BaseAddr, RegOffset, Data) \
Xil_Out32((BaseAddr) + (RegOffset), (Data))
/************************** Function Prototypes ******************************/
/*
* Perform reset operation to the devcfg interface
*/
void XDcfg_ResetHw(u32 BaseAddr);
/************************** Variable Definitions *****************************/
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */
@@ -1,349 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
*
* @file xdmaps.h
* @addtogroup dmaps_v2_4
* @{
* @details
*
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ------ -------- ----------------------------------------------
* 1.00 hbm 08/19/10 First Release
* 1.01a nm 12/20/12 Added definition XDMAPS_CHANNELS_PER_DEV which specifies
* the maximum number of channels.
* Replaced the usage of XPAR_XDMAPS_CHANNELS_PER_DEV
* with XDMAPS_CHANNELS_PER_DEV defined in xdmaps_hw.h.
* Added the tcl file to automatically generate the
* xparameters.h
* 1.02a sg 05/16/12 Made changes for doxygen and moved some function
* header from the xdmaps.h file to xdmaps.c file
* Other cleanup for coding guidelines and CR 657109
* and CR 657898
* The xdmaps_example_no_intr.c example is removed
* as it is using interrupts and is similar to
* the interrupt example - CR 652477
* 1.03a sg 07/16/2012 changed inline to __inline for CR665681
* 1.04a nm 10/22/2012 Fixed CR# 681671.
* 1.05a nm 04/15/2013 Fixed CR# 704396. Removed warnings when compiled
* with -Wall and -Wextra option in bsp.
* 05/01/2013 Fixed CR# 700189. Changed XDmaPs_BuildDmaProg()
* function description.
* Fixed CR# 704396. Removed unused variables
* UseM2MByte & MemBurstLen from XDmaPs_BuildDmaProg()
* function.
* 1.07a asa 11/02/13. Made changes to fix compilation issues for iarcc.
* Removed the PDBG prints. By default they were always
* defined out and never used. The PDBG is non-standard for
* Xilinx drivers and no other driver does something similar.
* Since there is no easy way to fix compilation issues with
* the IARCC compiler around PDBG, it is better to remove it.
* Users can always use xil_printfs if they want to debug.
* 2.0 adk 10/12/13 Updated as per the New Tcl API's
* 2.01 kpc 08/23/14 Fixed the IAR compiler reported errors
* 2.2 mus 08/12/16 Declared all inline functions in xdmaps.c as extern, to avoid
* linker error for IAR compiler
* 2.3 ms 01/23/17 Modified xil_printf statement in main function for all
* examples to ensure that "Successfully ran" and "Failed"
* strings are available in all examples. This is a fix
* for CR-965028.
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
* generation.
* 2.4 adk 13/08/18 Fixed armcc compiler warnings in the driver CR-1008310.
* </pre>
*
*****************************************************************************/
#ifndef XDMAPS_H /* prevent circular inclusions */
#define XDMAPS_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files ********************************/
#include "xparameters.h"
#include "xil_types.h"
#include "xil_assert.h"
#include "xstatus.h"
#include "xdmaps_hw.h"
/************************** Constant Definitions ****************************/
/**************************** Type Definitions ******************************/
/**
* This typedef contains configuration information for the device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddress; /**< Base address of device (IPIF) */
} XDmaPs_Config;
/** DMA channle control structure. It's for AXI bus transaction.
* This struct will be translated into a 32-bit channel control register value.
*/
typedef struct {
unsigned int EndianSwapSize; /**< Endian swap size. */
unsigned int DstCacheCtrl; /**< Destination cache control */
unsigned int DstProtCtrl; /**< Destination protection control */
unsigned int DstBurstLen; /**< Destination burst length */
unsigned int DstBurstSize; /**< Destination burst size */
unsigned int DstInc; /**< Destination incrementing or fixed
* address */
unsigned int SrcCacheCtrl; /**< Source cache control */
unsigned int SrcProtCtrl; /**< Source protection control */
unsigned int SrcBurstLen; /**< Source burst length */
unsigned int SrcBurstSize; /**< Source burst size */
unsigned int SrcInc; /**< Source incrementing or fixed
* address */
} XDmaPs_ChanCtrl;
/** DMA block descriptor stucture.
*/
typedef struct {
u32 SrcAddr; /**< Source starting address */
u32 DstAddr; /**< Destination starting address */
unsigned int Length; /**< Number of bytes for the block */
} XDmaPs_BD;
/**
* A DMA command consisits of a channel control struct, a block descriptor,
* a user defined program, a pointer pointing to generated DMA program, and
* execution result.
*
*/
typedef struct {
XDmaPs_ChanCtrl ChanCtrl; /**< Channel Control Struct */
XDmaPs_BD BD; /**< Together with SgLength field,
* it's a scatter-gather list.
*/
void *UserDmaProg; /**< If user wants the driver to
* execute their own DMA program,
* this field points to the DMA
* program.
*/
int UserDmaProgLength; /**< The length of user defined
* DMA program.
*/
void *GeneratedDmaProg; /**< The DMA program genreated
* by the driver. This field will be
* set if a user invokes the DMA
* program generation function. Or
* the DMA command is finished and
* a user informs the driver not to
* release the program buffer.
* This field has two purposes, one
* is to ask the driver to generate
* a DMA program while the DMAC is
* performaning DMA transactions. The
* other purpose is to debug the
* driver.
*/
int GeneratedDmaProgLength; /**< The length of the DMA program
* generated by the driver
*/
int DmaStatus; /**< 0 on success, otherwise error code
*/
u32 ChanFaultType; /**< Channel fault type in case of fault
*/
u32 ChanFaultPCAddr; /**< Channel fault PC address
*/
} XDmaPs_Cmd;
/**
* It's the done handler a user can set for a channel
*/
typedef void (*XDmaPsDoneHandler) (unsigned int Channel,
XDmaPs_Cmd *DmaCmd,
void *CallbackRef);
/**
* It's the fault handler a user can set for a channel
*/
typedef void (*XDmaPsFaultHandler) (unsigned int Channel,
XDmaPs_Cmd *DmaCmd,
void *CallbackRef);
#define XDMAPS_MAX_CHAN_BUFS 2
#define XDMAPS_CHAN_BUF_LEN 128
/**
* The XDmaPs_ProgBuf is the struct for a DMA program buffer.
*/
typedef struct {
char Buf[XDMAPS_CHAN_BUF_LEN]; /**< The actual buffer the holds the
* content */
unsigned Len; /**< The actual length of the DMA
* program in bytes. */
int Allocated; /**< A tag indicating whether the
* buffer is allocated or not */
} XDmaPs_ProgBuf;
/**
* The XDmaPs_ChannelData is a struct to book keep individual channel of
* the DMAC.
*/
typedef struct {
unsigned DevId; /**< Device id indicating which DMAC */
unsigned ChanId; /**< Channel number of the DMAC */
XDmaPs_ProgBuf ProgBufPool[XDMAPS_MAX_CHAN_BUFS]; /**< A pool of
program buffers*/
XDmaPsDoneHandler DoneHandler; /**< Done interrupt handler */
void *DoneRef; /**< Done interrupt callback data */
XDmaPs_Cmd *DmaCmdToHw; /**< DMA command being executed */
XDmaPs_Cmd *DmaCmdFromHw; /**< DMA command that is finished.
* This field is for debugging purpose
*/
int HoldDmaProg; /**< A tag indicating whether to hold the
* DMA program after the DMA is done.
*/
} XDmaPs_ChannelData;
/**
* The XDmaPs driver instance data structure. A pointer to an instance data
* structure is passed around by functions to refer to a specific driver
* instance.
*/
typedef struct {
XDmaPs_Config Config; /**< Configuration data structure */
int IsReady; /**< Device is Ready */
int CacheLength; /**< icache length */
XDmaPsFaultHandler FaultHandler; /**< fault interrupt handler */
void *FaultRef; /**< fault call back data */
XDmaPs_ChannelData Chans[XDMAPS_CHANNELS_PER_DEV];
/**<
* channel data
*/
} XDmaPs;
/*
* Functions implemented in xdmaps.c
*/
int XDmaPs_CfgInitialize(XDmaPs *InstPtr,
XDmaPs_Config *Config,
u32 EffectiveAddr);
int XDmaPs_Start(XDmaPs *InstPtr, unsigned int Channel,
XDmaPs_Cmd *Cmd,
int HoldDmaProg);
int XDmaPs_IsActive(XDmaPs *InstPtr, unsigned int Channel);
int XDmaPs_GenDmaProg(XDmaPs *InstPtr, unsigned int Channel,
XDmaPs_Cmd *Cmd);
int XDmaPs_FreeDmaProg(XDmaPs *InstPtr, unsigned int Channel,
XDmaPs_Cmd *Cmd);
void XDmaPs_Print_DmaProg(XDmaPs_Cmd *Cmd);
int XDmaPs_ResetManager(XDmaPs *InstPtr);
int XDmaPs_ResetChannel(XDmaPs *InstPtr, unsigned int Channel);
int XDmaPs_SetDoneHandler(XDmaPs *InstPtr,
unsigned Channel,
XDmaPsDoneHandler DoneHandler,
void *CallbackRef);
int XDmaPs_SetFaultHandler(XDmaPs *InstPtr,
XDmaPsFaultHandler FaultHandler,
void *CallbackRef);
void XDmaPs_Print_DmaProg(XDmaPs_Cmd *Cmd);
int XDmaPs_Instr_DMARMB(char *DmaProg);
int XDmaPs_Instr_DMAWMB(char *DmaProg);
/**
* To avoid linking error,Declare all inline functions as extern for
* IAR compiler
*/
#ifdef __ICCARM__
extern INLINE int XDmaPs_Instr_DMAEND(char *DmaProg);
extern INLINE void XDmaPs_Memcpy4(char *Dst, char *Src);
extern INLINE int XDmaPs_Instr_DMAGO(char *DmaProg, unsigned int Cn,
u32 Imm, unsigned int Ns);
extern INLINE int XDmaPs_Instr_DMALD(char *DmaProg);
extern INLINE int XDmaPs_Instr_DMALP(char *DmaProg, unsigned Lc,
unsigned LoopIterations);
extern INLINE int XDmaPs_Instr_DMALPEND(char *DmaProg, char *BodyStart, unsigned Lc);
extern INLINE int XDmaPs_Instr_DMAMOV(char *DmaProg, unsigned Rd, u32 Imm);
extern INLINE int XDmaPs_Instr_DMANOP(char *DmaProg);
extern INLINE int XDmaPs_Instr_DMASEV(char *DmaProg, unsigned int EventNumber);
extern INLINE int XDmaPs_Instr_DMAST(char *DmaProg);
extern INLINE unsigned XDmaPs_ToEndianSwapSizeBits(unsigned int EndianSwapSize);
extern INLINE unsigned XDmaPs_ToBurstSizeBits(unsigned BurstSize);
#endif
/**
* Driver done interrupt service routines for the channels.
* We need this done ISR mainly because the driver needs to release the
* DMA program buffer. This is the one that connects the GIC
*/
void XDmaPs_DoneISR_0(XDmaPs *InstPtr);
void XDmaPs_DoneISR_1(XDmaPs *InstPtr);
void XDmaPs_DoneISR_2(XDmaPs *InstPtr);
void XDmaPs_DoneISR_3(XDmaPs *InstPtr);
void XDmaPs_DoneISR_4(XDmaPs *InstPtr);
void XDmaPs_DoneISR_5(XDmaPs *InstPtr);
void XDmaPs_DoneISR_6(XDmaPs *InstPtr);
void XDmaPs_DoneISR_7(XDmaPs *InstPtr);
/**
* Driver fault interrupt service routine
*/
void XDmaPs_FaultISR(XDmaPs *InstPtr);
/*
* Static loopup function implemented in xdmaps_sinit.c
*/
XDmaPs_Config *XDmaPs_LookupConfig(u16 DeviceId);
/*
* self-test functions in xdmaps_selftest.c
*/
int XDmaPs_SelfTest(XDmaPs *InstPtr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */
@@ -1,289 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xdmaps_hw.h
* @addtogroup dmaps_v2_4
* @{
*
* This header file contains the hardware interface of an XDmaPs device.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ----------------------------------------------
* 1.00a hbm 08/18/10 First Release
* 1.01a nm 12/20/12 Added definition XDMAPS_CHANNELS_PER_DEV which specifies
* the maximum number of channels.
* Replaced the usage of XPAR_XDMAPS_CHANNELS_PER_DEV
* with XDMAPS_CHANNELS_PER_DEV defined in xdmaps_hw.h
* 1.02a sg 05/16/12 Made changes for doxygen
* 1.06a kpc 07/10/13 Added function prototype
* </pre>
*
******************************************************************************/
#ifndef XDMAPS_HW_H /* prevent circular inclusions */
#define XDMAPS_HW_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/** @name Register Map
*
* Register offsets for the DMAC.
* @{
*/
#define XDMAPS_DS_OFFSET 0x000 /* DMA Status Register */
#define XDMAPS_DPC_OFFSET 0x004 /* DMA Program Counter Rregister */
#define XDMAPS_INTEN_OFFSET 0X020 /* DMA Interrupt Enable Register */
#define XDMAPS_ES_OFFSET 0x024 /* DMA Event Status Register */
#define XDMAPS_INTSTATUS_OFFSET 0x028 /* DMA Interrupt Status Register
*/
#define XDMAPS_INTCLR_OFFSET 0x02c /* DMA Interrupt Clear Register */
#define XDMAPS_FSM_OFFSET 0x030 /* DMA Fault Status DMA Manager
* Register
*/
#define XDMAPS_FSC_OFFSET 0x034 /* DMA Fault Status DMA Chanel Register
*/
#define XDMAPS_FTM_OFFSET 0x038 /* DMA Fault Type DMA Manager Register */
#define XDMAPS_FTC0_OFFSET 0x040 /* DMA Fault Type for DMA Channel 0 */
/*
* The offset for the rest of the FTC registers is calculated as
* FTC0 + dev_chan_num * 4
*/
#define XDmaPs_FTCn_OFFSET(ch) (XDMAPS_FTC0_OFFSET + (ch) * 4)
#define XDMAPS_CS0_OFFSET 0x100 /* Channel Status for DMA Channel 0 */
/*
* The offset for the rest of the CS registers is calculated as
* CS0 + * dev_chan_num * 0x08
*/
#define XDmaPs_CSn_OFFSET(ch) (XDMAPS_CS0_OFFSET + (ch) * 8)
#define XDMAPS_CPC0_OFFSET 0x104 /* Channel Program Counter for DMA
* Channel 0
*/
/*
* The offset for the rest of the CPC registers is calculated as
* CPC0 + dev_chan_num * 0x08
*/
#define XDmaPs_CPCn_OFFSET(ch) (XDMAPS_CPC0_OFFSET + (ch) * 8)
#define XDMAPS_SA_0_OFFSET 0x400 /* Source Address Register for DMA
* Channel 0
*/
/* The offset for the rest of the SA registers is calculated as
* SA_0 + dev_chan_num * 0x20
*/
#define XDmaPs_SA_n_OFFSET(ch) (XDMAPS_SA_0_OFFSET + (ch) * 0x20)
#define XDMAPS_DA_0_OFFSET 0x404 /* Destination Address Register for
* DMA Channel 0
*/
/* The offset for the rest of the DA registers is calculated as
* DA_0 + dev_chan_num * 0x20
*/
#define XDmaPs_DA_n_OFFSET(ch) (XDMAPS_DA_0_OFFSET + (ch) * 0x20)
#define XDMAPS_CC_0_OFFSET 0x408 /* Channel Control Register for
* DMA Channel 0
*/
/*
* The offset for the rest of the CC registers is calculated as
* CC_0 + dev_chan_num * 0x20
*/
#define XDmaPs_CC_n_OFFSET(ch) (XDMAPS_CC_0_OFFSET + (ch) * 0x20)
#define XDMAPS_LC0_0_OFFSET 0x40C /* Loop Counter 0 for DMA Channel 0 */
/*
* The offset for the rest of the LC0 registers is calculated as
* LC_0 + dev_chan_num * 0x20
*/
#define XDmaPs_LC0_n_OFFSET(ch) (XDMAPS_LC0_0_OFFSET + (ch) * 0x20)
#define XDMAPS_LC1_0_OFFSET 0x410 /* Loop Counter 1 for DMA Channel 0 */
/*
* The offset for the rest of the LC1 registers is calculated as
* LC_0 + dev_chan_num * 0x20
*/
#define XDmaPs_LC1_n_OFFSET(ch) (XDMAPS_LC1_0_OFFSET + (ch) * 0x20)
#define XDMAPS_DBGSTATUS_OFFSET 0xD00 /* Debug Status Register */
#define XDMAPS_DBGCMD_OFFSET 0xD04 /* Debug Command Register */
#define XDMAPS_DBGINST0_OFFSET 0xD08 /* Debug Instruction 0 Register */
#define XDMAPS_DBGINST1_OFFSET 0xD0C /* Debug Instruction 1 Register */
#define XDMAPS_CR0_OFFSET 0xE00 /* Configuration Register 0 */
#define XDMAPS_CR1_OFFSET 0xE04 /* Configuration Register 1 */
#define XDMAPS_CR2_OFFSET 0xE08 /* Configuration Register 2 */
#define XDMAPS_CR3_OFFSET 0xE0C /* Configuration Register 3 */
#define XDMAPS_CR4_OFFSET 0xE10 /* Configuration Register 4 */
#define XDMAPS_CRDN_OFFSET 0xE14 /* Configuration Register Dn */
#define XDMAPS_PERIPH_ID_0_OFFSET 0xFE0 /* Peripheral Identification
* Register 0
*/
#define XDMAPS_PERIPH_ID_1_OFFSET 0xFE4 /* Peripheral Identification
* Register 1
*/
#define XDMAPS_PERIPH_ID_2_OFFSET 0xFE8 /* Peripheral Identification
* Register 2
*/
#define XDMAPS_PERIPH_ID_3_OFFSET 0xFEC /* Peripheral Identification
* Register 3
*/
#define XDMAPS_PCELL_ID_0_OFFSET 0xFF0 /* PrimeCell Identification
* Register 0
*/
#define XDMAPS_PCELL_ID_1_OFFSET 0xFF4 /* PrimeCell Identification
* Register 1
*/
#define XDMAPS_PCELL_ID_2_OFFSET 0xFF8 /* PrimeCell Identification
* Register 2
*/
#define XDMAPS_PCELL_ID_3_OFFSET 0xFFC /* PrimeCell Identification
* Register 3
*/
/*
* Some useful register masks
*/
#define XDMAPS_DS_DMA_STATUS 0x0F /* DMA status mask */
#define XDMAPS_DS_DMA_STATUS_STOPPED 0x00 /* debug status busy mask */
#define XDMAPS_DBGSTATUS_BUSY 0x01 /* debug status busy mask */
#define XDMAPS_CS_ACTIVE_MASK 0x07 /* channel status active mask,
* llast 3 bits of CS register
*/
#define XDMAPS_CR1_I_CACHE_LEN_MASK 0x07 /* i_cache_len mask */
/*
* XDMAPS_DBGINST0 - constructs the word for the Debug Instruction-0 Register.
* @b1: Instruction byte 1
* @b0: Instruction byte 0
* @ch: Channel number
* @dbg_th: Debug thread encoding: 0 = DMA manager thread, 1 = DMA channel
*/
#define XDmaPs_DBGINST0(b1, b0, ch, dbg_th) \
(((b1) << 24) | ((b0) << 16) | (((ch) & 0x7) << 8) | ((dbg_th & 0x1)))
/* @} */
/** @name Control Register
*
* The Control register (CR) controls the major functions of the device.
*
* Control Register Bit Definition
*/
/* @}*/
#define XDMAPS_CHANNELS_PER_DEV 8
/** @name Mode Register
*
* The mode register (MR) defines the mode of transfer as well as the data
* format. If this register is modified during transmission or reception,
* data validity cannot be guaranteed.
*
* Mode Register Bit Definition
* @{
*/
/* @} */
/** @name Interrupt Registers
*
* Interrupt control logic uses the interrupt enable register (IER) and the
* interrupt disable register (IDR) to set the value of the bits in the
* interrupt mask register (IMR). The IMR determines whether to pass an
* interrupt to the interrupt status register (ISR).
* Writing a 1 to IER Enbables an interrupt, writing a 1 to IDR disables an
* interrupt. IMR and ISR are read only, and IER and IDR are write only.
* Reading either IER or IDR returns 0x00.
*
* All four registers have the same bit definitions.
*
* @{
*/
/* @} */
#define XDMAPS_INTCLR_ALL_MASK 0xFF
#define XDmaPs_ReadReg(BaseAddress, RegOffset) \
Xil_In32((BaseAddress) + (RegOffset))
/***************************************************************************/
/**
* Write a DMAC register.
*
* @param BaseAddress contains the base address of the device.
* @param RegOffset contains the offset from the base address of the device.
* @param RegisterValue is the value to be written to the register.
*
* @return None.
*
* @note
* C-Style signature:
* void XDmaPs_WriteReg(u32 BaseAddress, int RegOffset,
* u32 RegisterValue)
******************************************************************************/
#define XDmaPs_WriteReg(BaseAddress, RegOffset, RegisterValue) \
Xil_Out32((BaseAddress) + (RegOffset), (RegisterValue))
/************************** Variable Definitions *****************************/
/************************** Function Prototypes *****************************/
/*
* Perform reset operation to the dmaps interface
*/
void XDmaPs_ResetHw(u32 BaseAddr);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */
@@ -1,183 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xenv.h
*
* Defines common services that are typically found in a host operating.
* environment. This include file simply includes an OS specific file based
* on the compile-time constant BUILD_ENV_*, where * is the name of the target
* environment.
*
* All services are defined as macros.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00b ch 10/24/02 Added XENV_LINUX
* 1.00a rmm 04/17/02 First release
* </pre>
*
******************************************************************************/
#ifndef XENV_H /* prevent circular inclusions */
#define XENV_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/*
* Select which target environment we are operating under
*/
/* VxWorks target environment */
#if defined XENV_VXWORKS
#include "xenv_vxworks.h"
/* Linux target environment */
#elif defined XENV_LINUX
#include "xenv_linux.h"
/* Unit test environment */
#elif defined XENV_UNITTEST
#include "ut_xenv.h"
/* Integration test environment */
#elif defined XENV_INTTEST
#include "int_xenv.h"
/* Standalone environment selected */
#else
#include "xenv_standalone.h"
#endif
/*
* The following comments specify the types and macro wrappers that are
* expected to be defined by the target specific header files
*/
/**************************** Type Definitions *******************************/
/*****************************************************************************/
/**
*
* XENV_TIME_STAMP
*
* A structure that contains a time stamp used by other time stamp macros
* defined below. This structure is processor dependent.
*/
/***************** Macros (Inline Functions) Definitions *********************/
/*****************************************************************************/
/**
*
* XENV_MEM_COPY(void *DestPtr, void *SrcPtr, unsigned Bytes)
*
* Copies a non-overlapping block of memory.
*
* @param DestPtr is the destination address to copy data to.
* @param SrcPtr is the source address to copy data from.
* @param Bytes is the number of bytes to copy.
*
* @return None
*/
/*****************************************************************************/
/**
*
* XENV_MEM_FILL(void *DestPtr, char Data, unsigned Bytes)
*
* Fills an area of memory with constant data.
*
* @param DestPtr is the destination address to set.
* @param Data contains the value to set.
* @param Bytes is the number of bytes to set.
*
* @return None
*/
/*****************************************************************************/
/**
*
* XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr)
*
* Samples the processor's or external timer's time base counter.
*
* @param StampPtr is the storage for the retrieved time stamp.
*
* @return None
*/
/*****************************************************************************/
/**
*
* XENV_TIME_STAMP_DELTA_US(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr)
*
* Computes the delta between the two time stamps.
*
* @param Stamp1Ptr - First sampled time stamp.
* @param Stamp1Ptr - Sedond sampled time stamp.
*
* @return An unsigned int value with units of microseconds.
*/
/*****************************************************************************/
/**
*
* XENV_TIME_STAMP_DELTA_MS(XTIME_STAMP *Stamp1Ptr, XTIME_STAMP* Stamp2Ptr)
*
* Computes the delta between the two time stamps.
*
* @param Stamp1Ptr - First sampled time stamp.
* @param Stamp1Ptr - Sedond sampled time stamp.
*
* @return An unsigned int value with units of milliseconds.
*/
/*****************************************************************************//**
*
* XENV_USLEEP(unsigned delay)
*
* Delay the specified number of microseconds.
*
* @param delay is the number of microseconds to delay.
*
* @return None
*/
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
@@ -1,364 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2002 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xenv_standalone.h
*
* Defines common services specified by xenv.h.
*
* @note
* This file is not intended to be included directly by driver code.
* Instead, the generic xenv.h file is intended to be included by driver
* code.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a wgr 02/28/07 Added cache handling macros.
* 1.00a wgr 02/27/07 Simplified code. Deprecated old-style macro names.
* 1.00a rmm 01/24/06 Implemented XENV_USLEEP. Assume implementation is being
* used under Xilinx standalone BSP.
* 1.00a xd 11/03/04 Improved support for doxygen.
* 1.00a rmm 03/21/02 First release
* 1.00a wgr 03/22/07 Converted to new coding style.
* 1.00a rpm 06/29/07 Added udelay macro for standalone
* 1.00a xd 07/19/07 Included xparameters.h as XPAR_ constants are referred
* to in MICROBLAZE section
* 1.00a ecm 09/19/08 updated for v7.20 of Microblaze, new functionality
*
* </pre>
*
*
******************************************************************************/
#ifndef XENV_STANDALONE_H
#define XENV_STANDALONE_H
#include "xil_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
/******************************************************************************
*
* Get the processor dependent includes
*
******************************************************************************/
#include <string.h>
#if defined __MICROBLAZE__
# include "mb_interface.h"
# include "xparameters.h" /* XPAR constants used below in MB section */
#elif defined __PPC__
# include "sleep.h"
# include "xcache_l.h" /* also include xcache_l.h for caching macros */
#endif
/******************************************************************************
*
* MEMCPY / MEMSET related macros.
*
* The following are straight forward implementations of memset and memcpy.
*
* NOTE: memcpy may not work if source and target memory area are overlapping.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* Copies a non-overlapping block of memory.
*
* @param DestPtr
* Destination address to copy data to.
*
* @param SrcPtr
* Source address to copy data from.
*
* @param Bytes
* Number of bytes to copy.
*
* @return None.
*
* @note
* The use of XENV_MEM_COPY is deprecated. Use memcpy() instead.
*
* @note
* This implemention MAY BREAK work if source and target memory
* area are overlapping.
*
*****************************************************************************/
#define XENV_MEM_COPY(DestPtr, SrcPtr, Bytes) \
memcpy((void *) DestPtr, (const void *) SrcPtr, (size_t) Bytes)
/*****************************************************************************/
/**
*
* Fills an area of memory with constant data.
*
* @param DestPtr
* Destination address to copy data to.
*
* @param Data
* Value to set.
*
* @param Bytes
* Number of bytes to copy.
*
* @return None.
*
* @note
* The use of XENV_MEM_FILL is deprecated. Use memset() instead.
*
*****************************************************************************/
#define XENV_MEM_FILL(DestPtr, Data, Bytes) \
memset((void *) DestPtr, (s32) Data, (size_t) Bytes)
/******************************************************************************
*
* TIME related macros
*
******************************************************************************/
/**
* A structure that contains a time stamp used by other time stamp macros
* defined below. This structure is processor dependent.
*/
typedef s32 XENV_TIME_STAMP;
/*****************************************************************************/
/**
*
* Time is derived from the 64 bit PPC timebase register
*
* @param StampPtr is the storage for the retrieved time stamp.
*
* @return None.
*
* @note
*
* Signature: void XENV_TIME_STAMP_GET(XTIME_STAMP *StampPtr)
* <br><br>
* This macro must be implemented by the user.
*
*****************************************************************************/
#define XENV_TIME_STAMP_GET(StampPtr)
/*****************************************************************************/
/**
*
* This macro is not yet implemented and always returns 0.
*
* @param Stamp1Ptr is the first sampled time stamp.
* @param Stamp2Ptr is the second sampled time stamp.
*
* @return 0
*
* @note
*
* This macro must be implemented by the user.
*
*****************************************************************************/
#define XENV_TIME_STAMP_DELTA_US(Stamp1Ptr, Stamp2Ptr) (0)
/*****************************************************************************/
/**
*
* This macro is not yet implemented and always returns 0.
*
* @param Stamp1Ptr is the first sampled time stamp.
* @param Stamp2Ptr is the second sampled time stamp.
*
* @return 0
*
* @note
*
* This macro must be implemented by the user.
*
*****************************************************************************/
#define XENV_TIME_STAMP_DELTA_MS(Stamp1Ptr, Stamp2Ptr) (0)
/*****************************************************************************/
/**
* XENV_USLEEP(unsigned delay)
*
* Delay the specified number of microseconds. Not implemented without OS
* support.
*
* @param delay
* Number of microseconds to delay.
*
* @return None.
*
*****************************************************************************/
#ifdef __PPC__
#define XENV_USLEEP(delay) usleep(delay)
#define udelay(delay) usleep(delay)
#else
#define XENV_USLEEP(delay)
#define udelay(delay)
#endif
/******************************************************************************
*
* CACHE handling macros / mappings
*
******************************************************************************/
/******************************************************************************
*
* Processor independent macros
*
******************************************************************************/
#define XCACHE_ENABLE_CACHE() \
{ XCACHE_ENABLE_DCACHE(); XCACHE_ENABLE_ICACHE(); }
#define XCACHE_DISABLE_CACHE() \
{ XCACHE_DISABLE_DCACHE(); XCACHE_DISABLE_ICACHE(); }
/******************************************************************************
*
* MicroBlaze case
*
* NOTE: Currently the following macros will only work on systems that contain
* only ONE MicroBlaze processor. Also, the macros will only be enabled if the
* system is built using a xparameters.h file.
*
******************************************************************************/
#if defined __MICROBLAZE__
/* Check if MicroBlaze data cache was built into the core.
*/
#if (XPAR_MICROBLAZE_USE_DCACHE == 1)
# define XCACHE_ENABLE_DCACHE() microblaze_enable_dcache()
# define XCACHE_DISABLE_DCACHE() microblaze_disable_dcache()
# define XCACHE_INVALIDATE_DCACHE() microblaze_invalidate_dcache()
# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \
microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len))
#if (XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK == 1)
# define XCACHE_FLUSH_DCACHE() microblaze_flush_dcache()
# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \
microblaze_flush_dcache_range((s32)(Addr), (s32)(Len))
#else
# define XCACHE_FLUSH_DCACHE() microblaze_invalidate_dcache()
# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \
microblaze_invalidate_dcache_range((s32)(Addr), (s32)(Len))
#endif /*XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK*/
#else
# define XCACHE_ENABLE_DCACHE()
# define XCACHE_DISABLE_DCACHE()
# define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len)
# define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len)
#endif /*XPAR_MICROBLAZE_USE_DCACHE*/
/* Check if MicroBlaze instruction cache was built into the core.
*/
#if (XPAR_MICROBLAZE_USE_ICACHE == 1)
# define XCACHE_ENABLE_ICACHE() microblaze_enable_icache()
# define XCACHE_DISABLE_ICACHE() microblaze_disable_icache()
# define XCACHE_INVALIDATE_ICACHE() microblaze_invalidate_icache()
# define XCACHE_INVALIDATE_ICACHE_RANGE(Addr, Len) \
microblaze_invalidate_icache_range((s32)(Addr), (s32)(Len))
#else
# define XCACHE_ENABLE_ICACHE()
# define XCACHE_DISABLE_ICACHE()
#endif /*XPAR_MICROBLAZE_USE_ICACHE*/
/******************************************************************************
*
* PowerPC case
*
* Note that the XCACHE_ENABLE_xxx functions are hardcoded to enable a
* specific memory region (0x80000001). Each bit (0-30) in the regions
* bitmask stands for 128MB of memory. Bit 31 stands for the upper 2GB
* range.
*
* regions --> cached address range
* ------------|--------------------------------------------------
* 0x80000000 | [0, 0x7FFFFFF]
* 0x00000001 | [0xF8000000, 0xFFFFFFFF]
* 0x80000001 | [0, 0x7FFFFFF],[0xF8000000, 0xFFFFFFFF]
*
******************************************************************************/
#elif defined __PPC__
#define XCACHE_ENABLE_DCACHE() XCache_EnableDCache(0x80000001)
#define XCACHE_DISABLE_DCACHE() XCache_DisableDCache()
#define XCACHE_ENABLE_ICACHE() XCache_EnableICache(0x80000001)
#define XCACHE_DISABLE_ICACHE() XCache_DisableICache()
#define XCACHE_INVALIDATE_DCACHE_RANGE(Addr, Len) \
XCache_InvalidateDCacheRange((u32)(Addr), (u32)(Len))
#define XCACHE_FLUSH_DCACHE_RANGE(Addr, Len) \
XCache_FlushDCacheRange((u32)(Addr), (u32)(Len))
#define XCACHE_INVALIDATE_ICACHE() XCache_InvalidateICache()
/******************************************************************************
*
* Unknown processor / architecture
*
******************************************************************************/
#else
/* #error "Unknown processor / architecture. Must be MicroBlaze or PowerPC." */
#endif
#ifdef __cplusplus
}
#endif
#endif /* #ifndef XENV_STANDALONE_H */
@@ -1,283 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xgpiops.h
* @addtogroup gpiops_v3_5
* @{
* @details
*
* The Xilinx PS GPIO driver. This driver supports the Xilinx PS GPIO
* Controller.
*
* The GPIO Controller supports the following features:
* - 4 banks
* - Masked writes (There are no masked reads)
* - Bypass mode
* - Configurable Interrupts (Level/Edge)
*
* This driver is intended to be RTOS and processor independent. Any needs for
* dynamic memory management, threads or thread mutual exclusion, virtual
* memory, or cache control must be satisfied by the layer above this driver.
* This driver supports all the features listed above, if applicable.
*
* <b>Driver Description</b>
*
* The device driver enables higher layer software (e.g., an application) to
* communicate to the GPIO.
*
* <b>Interrupts</b>
*
* The driver provides interrupt management functions and an interrupt handler.
* Users of this driver need to provide callback functions. An interrupt handler
* example is available with the driver.
*
* <b>Threads</b>
*
* This driver is not thread safe. Any needs for threads or thread mutual
* exclusion must be satisfied by the layer above this driver.
*
* <b>Asserts</b>
*
* Asserts are used within all Xilinx drivers to enforce constraints on argument
* values. Asserts can be turned off on a system-wide basis by defining, at
* compile time, the NDEBUG identifier. By default, asserts are turned on and it
* is recommended that users leave asserts on during development.
*
* <b>Building the driver</b>
*
* The XGpioPs driver is composed of several source files. This allows the user
* to build and link only those parts of the driver that are necessary.
* <br><br>
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a sv 01/15/10 First Release
* 1.01a sv 04/15/12 Removed the APIs XGpioPs_SetMode, XGpioPs_SetModePin
* XGpioPs_GetMode, XGpioPs_GetModePin as they are not
* relevant to Zynq device.The interrupts are disabled
* for output pins on all banks during initialization.
* 1.02a hk 08/22/13 Added low level reset API
* 2.1 hk 04/29/14 Use Input data register DATA_RO for read. CR# 771667.
* 2.2 sk 10/13/14 Used Pin number in Bank instead of pin number
* passed to APIs. CR# 822636
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.1 kvn 04/13/15 Add support for Zynq Ultrascale+ MP. CR# 856980.
* ms 03/17/17 Added readme.txt file in examples folder for doxygen
* generation.
* ms 04/05/17 Added tabspace for return statements in functions of
* gpiops examples for proper documentation while
* generating doxygen.
* 3.3 ms 04/17/17 Added notes about gpio input and output pin description
* for zcu102 and zc702 boards in polled and interrupt
* example, configured Interrupt pin to input pin for
* proper functioning of interrupt example.
* 3.4 aru 08/17/18 Resolved MISRA-C mandatory violations. CR# 1007751
* 3.5 sne 03/01/19 Fixes violations according to MISRAC-2012
* in saftey mode and modified the code such as
* Use of mixed mode arithmetic,Declared the poiner param
* as Pointer to const,Casting operation to a pointer,
* Literal value requires a U suffix.
* 3.5 sne 03/14/19 Added Versal support.
* </pre>
*
******************************************************************************/
#ifndef XGPIOPS_H /* prevent circular inclusions */
#define XGPIOPS_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xstatus.h"
#include "xgpiops_hw.h"
#include "xplatform_info.h"
/************************** Constant Definitions *****************************/
/** @name Interrupt types
* @{
* The following constants define the interrupt types that can be set for each
* GPIO pin.
*/
#define XGPIOPS_IRQ_TYPE_EDGE_RISING 0x00U /**< Interrupt on Rising edge */
#define XGPIOPS_IRQ_TYPE_EDGE_FALLING 0x01U /**< Interrupt Falling edge */
#define XGPIOPS_IRQ_TYPE_EDGE_BOTH 0x02U /**< Interrupt on both edges */
#define XGPIOPS_IRQ_TYPE_LEVEL_HIGH 0x03U /**< Interrupt on high level */
#define XGPIOPS_IRQ_TYPE_LEVEL_LOW 0x04U /**< Interrupt on low level */
/*@}*/
#define XGPIOPS_BANK_MAX_PINS (u32)32 /**< Max pins in a GPIO bank */
#define XGPIOPS_BANK0 0x00U /**< GPIO Bank 0 */
#define XGPIOPS_BANK1 0x01U /**< GPIO Bank 1 */
#define XGPIOPS_BANK2 0x02U /**< GPIO Bank 2 */
#define XGPIOPS_BANK3 0x03U /**< GPIO Bank 3 */
#ifdef XPAR_PSU_GPIO_0_BASEADDR
#define XGPIOPS_BANK4 0x04U /**< GPIO Bank 4 */
#define XGPIOPS_BANK5 0x05U /**< GPIO Bank 5 */
#endif
#define XGPIOPS_MAX_BANKS_ZYNQMP 0x06U /**< Max banks in a
* Zynq Ultrascale+ MP GPIO device
*/
#define XGPIOPS_MAX_BANKS 0x04U /**< Max banks in a Zynq GPIO device */
#define XGPIOPS_DEVICE_MAX_PIN_NUM_ZYNQMP (u32)174 /**< Max pins in the
* Zynq Ultrascale+ MP GPIO device
* 0 - 25, Bank 0
* 26 - 51, Bank 1
* 52 - 77, Bank 2
* 78 - 109, Bank 3
* 110 - 141, Bank 4
* 142 - 173, Bank 5
*/
#define XGPIOPS_DEVICE_MAX_PIN_NUM (u32)118 /**< Max pins in the Zynq GPIO device
* 0 - 31, Bank 0
* 32 - 53, Bank 1
* 54 - 85, Bank 2
* 86 - 117, Bank 3
*/
/**************************** Type Definitions *******************************/
/****************************************************************************/
/**
* This handler data type allows the user to define a callback function to
* handle the interrupts for the GPIO device. The application using this
* driver is expected to define a handler of this type, to support interrupt
* driven mode. The handler executes in an interrupt context such that minimal
* processing should be performed.
*
* @param CallBackRef is a callback reference passed in by the upper layer
* when setting the callback functions for a GPIO bank. It is
* passed back to the upper layer when the callback is invoked. Its
* type is not important to the driver component, so it is a void
* pointer.
* @param Bank is the bank for which the interrupt status has changed.
* @param Status is the Interrupt status of the GPIO bank.
*
*****************************************************************************/
typedef void (*XGpioPs_Handler) (void *CallBackRef, u32 Bank, u32 Status);
/**
* This typedef contains configuration information for a device.
*/
typedef struct {
u16 DeviceId; /**< Unique ID of device */
u32 BaseAddr; /**< Register base address */
} XGpioPs_Config;
/**
* The XGpioPs driver instance data. The user is required to allocate a
* variable of this type for the GPIO device in the system. A pointer
* to a variable of this type is then passed to the driver API functions.
*/
typedef struct {
XGpioPs_Config GpioConfig; /**< Device configuration */
u32 IsReady; /**< Device is initialized and ready */
XGpioPs_Handler Handler; /**< Status handlers for all banks */
void *CallBackRef; /**< Callback ref for bank handlers */
u32 Platform; /**< Platform data */
u32 MaxPinNum; /**< Max pins in the GPIO device */
u8 MaxBanks; /**< Max banks in a GPIO device */
u32 PmcGpio; /**< Flag for accessing PS GPIO for versal*/
} XGpioPs;
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/* Functions in xgpiops.c */
s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, const XGpioPs_Config *ConfigPtr,
u32 EffectiveAddr);
/* Bank APIs in xgpiops.c */
u32 XGpioPs_Read(const XGpioPs *InstancePtr, u8 Bank);
void XGpioPs_Write(const XGpioPs *InstancePtr, u8 Bank, u32 Data);
void XGpioPs_SetDirection(const XGpioPs *InstancePtr, u8 Bank, u32 Direction);
u32 XGpioPs_GetDirection(const XGpioPs *InstancePtr, u8 Bank);
void XGpioPs_SetOutputEnable(const XGpioPs *InstancePtr, u8 Bank, u32 OpEnable);
u32 XGpioPs_GetOutputEnable(const XGpioPs *InstancePtr, u8 Bank);
#ifdef versal
void XGpioPs_GetBankPin(const XGpioPs *InstancePtr,u8 PinNumber,u8 *BankNumber, u8 *PinNumberInBank);
#else
void XGpioPs_GetBankPin(u8 PinNumber,u8 *BankNumber, u8 *PinNumberInBank);
#endif
/* Pin APIs in xgpiops.c */
u32 XGpioPs_ReadPin(const XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_WritePin(const XGpioPs *InstancePtr, u32 Pin, u32 Data);
void XGpioPs_SetDirectionPin(const XGpioPs *InstancePtr, u32 Pin, u32 Direction);
u32 XGpioPs_GetDirectionPin(const XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_SetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin, u32 OpEnable);
u32 XGpioPs_GetOutputEnablePin(const XGpioPs *InstancePtr, u32 Pin);
/* Diagnostic functions in xgpiops_selftest.c */
s32 XGpioPs_SelfTest(const XGpioPs *InstancePtr);
/* Functions in xgpiops_intr.c */
/* Bank APIs in xgpiops_intr.c */
void XGpioPs_IntrEnable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask);
void XGpioPs_IntrDisable(const XGpioPs *InstancePtr, u8 Bank, u32 Mask);
u32 XGpioPs_IntrGetEnabled(const XGpioPs *InstancePtr, u8 Bank);
u32 XGpioPs_IntrGetStatus(const XGpioPs *InstancePtr, u8 Bank);
void XGpioPs_IntrClear(const XGpioPs *InstancePtr, u8 Bank, u32 Mask);
void XGpioPs_SetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 IntrType,
u32 IntrPolarity, u32 IntrOnAny);
void XGpioPs_GetIntrType(const XGpioPs *InstancePtr, u8 Bank, u32 *IntrType,
u32 *IntrPolarity, u32 *IntrOnAny);
void XGpioPs_SetCallbackHandler(XGpioPs *InstancePtr, void *CallBackRef,
XGpioPs_Handler FuncPointer);
void XGpioPs_IntrHandler(const XGpioPs *InstancePtr);
/* Pin APIs in xgpiops_intr.c */
void XGpioPs_SetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin, u8 IrqType);
u8 XGpioPs_GetIntrTypePin(const XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_IntrEnablePin(const XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_IntrDisablePin(const XGpioPs *InstancePtr, u32 Pin);
u32 XGpioPs_IntrGetEnabledPin(const XGpioPs *InstancePtr, u32 Pin);
u32 XGpioPs_IntrGetStatusPin(const XGpioPs *InstancePtr, u32 Pin);
void XGpioPs_IntrClearPin(const XGpioPs *InstancePtr, u32 Pin);
/* Functions in xgpiops_sinit.c */
XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/** @} */
@@ -1,168 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2019 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xgpiops_hw.h
* @addtogroup gpiops_v3_5
* @{
*
* This header file contains the identifiers and basic driver functions (or
* macros) that can be used to access the device. Other driver functions
* are defined in xgpiops.h.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------
* 1.00a sv 01/15/10 First Release
* 1.02a hk 08/22/13 Added low level reset API function prototype and
* related constant definitions
* 3.00 kvn 02/13/15 Modified code for MISRA-C:2012 compliance.
* 3.1 kvn 04/13/15 Corrected reset values of banks.
* 3.5 sne 03/14/19 Added versal support.
* </pre>
*
******************************************************************************/
#ifndef XGPIOPS_HW_H /* prevent circular inclusions */
#define XGPIOPS_HW_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_assert.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
/** @name Register offsets for the GPIO. Each register is 32 bits.
* @{
*/
#define XGPIOPS_DATA_LSW_OFFSET 0x00000000U /* Mask and Data Register LSW, WO */
#define XGPIOPS_DATA_MSW_OFFSET 0x00000004U /* Mask and Data Register MSW, WO */
#define XGPIOPS_DATA_OFFSET 0x00000040U /* Data Register, RW */
#define XGPIOPS_DATA_RO_OFFSET 0x00000060U /* Data Register - Input, RO */
#define XGPIOPS_DIRM_OFFSET 0x00000204U /* Direction Mode Register, RW */
#define XGPIOPS_OUTEN_OFFSET 0x00000208U /* Output Enable Register, RW */
#define XGPIOPS_INTMASK_OFFSET 0x0000020CU /* Interrupt Mask Register, RO */
#define XGPIOPS_INTEN_OFFSET 0x00000210U /* Interrupt Enable Register, WO */
#define XGPIOPS_INTDIS_OFFSET 0x00000214U /* Interrupt Disable Register, WO*/
#define XGPIOPS_INTSTS_OFFSET 0x00000218U /* Interrupt Status Register, RO */
#define XGPIOPS_INTTYPE_OFFSET 0x0000021CU /* Interrupt Type Register, RW */
#define XGPIOPS_INTPOL_OFFSET 0x00000220U /* Interrupt Polarity Register, RW */
#define XGPIOPS_INTANY_OFFSET 0x00000224U /* Interrupt On Any Register, RW */
/* @} */
/** @name Register offsets for each Bank.
* @{
*/
#define XGPIOPS_DATA_MASK_OFFSET 0x00000008U /* Data/Mask Registers offset */
#define XGPIOPS_DATA_BANK_OFFSET 0x00000004U /* Data Registers offset */
#define XGPIOPS_REG_MASK_OFFSET 0x00000040U /* Registers offset */
/* @} */
/* For backwards compatibility */
#define XGPIOPS_BYPM_MASK_OFFSET (u32)0x40
/** @name Interrupt type reset values for each bank
* @{
*/
#ifdef XPAR_PSU_GPIO_0_BASEADDR
#define XGPIOPS_INTTYPE_BANK0_RESET 0x03FFFFFFU /* Resets specific to Zynq Ultrascale+ MP */
#define XGPIOPS_INTTYPE_BANK1_RESET 0x03FFFFFFU
#define XGPIOPS_INTTYPE_BANK2_RESET 0x03FFFFFFU
#else
#define XGPIOPS_INTTYPE_BANK0_RESET 0xFFFFFFFFU /* Resets specific to Zynq */
#define XGPIOPS_INTTYPE_BANK1_RESET 0x003FFFFFU
#define XGPIOPS_INTTYPE_BANK2_RESET 0xFFFFFFFFU
#endif
#define XGPIOPS_INTTYPE_BANK3_RESET 0xFFFFFFFFU /* Reset common to both platforms */
#define XGPIOPS_INTTYPE_BANK4_RESET 0xFFFFFFFFU /* Resets specific to Zynq Ultrascale+ MP */
#define XGPIOPS_INTTYPE_BANK5_RESET 0xFFFFFFFFU
/* @} */
#define XGPIOPS_PS_GPIO_BASEADDR 0xFF0B0000U /* Flag for Base Address for PS_GPIO in Versal */
#define XGPIOPS_ZERO 0U /* Flag for 0 Value */
#define XGPIOPS_ONE 1U /* Flag for 1 Value */
#define XGPIOPS_TWO 2U /* Flag for 2 Value */
#define XGPIOPS_THREE 3U /* Flag for 3 Value */
#define XGPIOPS_FOUR 4U /* Flag for 4 Value */
#define XGPIOPS_SIX 6U /* Flag for 6 Value */
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/****************************************************************************/
/**
*
* This macro reads the given register.
*
* @param BaseAddr is the base address of the device.
* @param RegOffset is the register offset to be read.
*
* @return The 32-bit value of the register
*
* @note None.
*
*****************************************************************************/
#define XGpioPs_ReadReg(BaseAddr, RegOffset) \
Xil_In32((BaseAddr) + (u32)(RegOffset))
/****************************************************************************/
/**
*
* This macro writes to the given register.
*
* @param BaseAddr is the base address of the device.
* @param RegOffset is the offset of the register to be written.
* @param Data is the 32-bit value to write to the register.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
#define XGpioPs_WriteReg(BaseAddr, RegOffset, Data) \
Xil_Out32((BaseAddr) + (u32)(RegOffset), (u32)(Data))
/************************** Function Prototypes ******************************/
void XGpioPs_ResetHw(u32 BaseAddress);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XGPIOPS_HW_H */
/** @} */
@@ -1,191 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2018 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_assert.h
*
* @addtogroup common_assert_apis Assert APIs and Macros
*
* The xil_assert.h file contains assert related functions and macros.
* Assert APIs/Macros specifies that a application program satisfies certain
* conditions at particular points in its execution. These function can be
* used by application programs to ensure that, application code is satisfying
* certain conditions.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a hbm 07/14/09 First release
* 6.0 kvn 05/31/16 Make Xil_AsserWait a global variable
* </pre>
*
******************************************************************************/
#ifndef XIL_ASSERT_H /* prevent circular inclusions */
#define XIL_ASSERT_H /* by using protection macros */
#include "xil_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
/************************** Constant Definitions *****************************/
#define XIL_ASSERT_NONE 0U
#define XIL_ASSERT_OCCURRED 1U
#define XNULL NULL
extern u32 Xil_AssertStatus;
extern s32 Xil_AssertWait;
extern void Xil_Assert(const char8 *File, s32 Line);
void XNullHandler(void *NullParameter);
/**
* This data type defines a callback to be invoked when an
* assert occurs. The callback is invoked only when asserts are enabled
*/
typedef void (*Xil_AssertCallback) (const char8 *File, s32 Line);
/***************** Macros (Inline Functions) Definitions *********************/
#ifndef NDEBUG
/*****************************************************************************/
/**
* @brief This assert macro is to be used for void functions. This in
* conjunction with the Xil_AssertWait boolean can be used to
* accomodate tests so that asserts which fail allow execution to
* continue.
*
* @param Expression: expression to be evaluated. If it evaluates to
* false, the assert occurs.
*
* @return Returns void unless the Xil_AssertWait variable is true, in which
* case no return is made and an infinite loop is entered.
*
******************************************************************************/
#define Xil_AssertVoid(Expression) \
{ \
if (Expression) { \
Xil_AssertStatus = XIL_ASSERT_NONE; \
} else { \
Xil_Assert(__FILE__, __LINE__); \
Xil_AssertStatus = XIL_ASSERT_OCCURRED; \
return; \
} \
}
/*****************************************************************************/
/**
* @brief This assert macro is to be used for functions that do return a
* value. This in conjunction with the Xil_AssertWait boolean can be
* used to accomodate tests so that asserts which fail allow execution
* to continue.
*
* @param Expression: expression to be evaluated. If it evaluates to false,
* the assert occurs.
*
* @return Returns 0 unless the Xil_AssertWait variable is true, in which
* case no return is made and an infinite loop is entered.
*
******************************************************************************/
#define Xil_AssertNonvoid(Expression) \
{ \
if (Expression) { \
Xil_AssertStatus = XIL_ASSERT_NONE; \
} else { \
Xil_Assert(__FILE__, __LINE__); \
Xil_AssertStatus = XIL_ASSERT_OCCURRED; \
return 0; \
} \
}
/*****************************************************************************/
/**
* @brief Always assert. This assert macro is to be used for void functions.
* Use for instances where an assert should always occur.
*
* @return Returns void unless the Xil_AssertWait variable is true, in which
* case no return is made and an infinite loop is entered.
*
******************************************************************************/
#define Xil_AssertVoidAlways() \
{ \
Xil_Assert(__FILE__, __LINE__); \
Xil_AssertStatus = XIL_ASSERT_OCCURRED; \
return; \
}
/*****************************************************************************/
/**
* @brief Always assert. This assert macro is to be used for functions that
* do return a value. Use for instances where an assert should always
* occur.
*
* @return Returns void unless the Xil_AssertWait variable is true, in which
* case no return is made and an infinite loop is entered.
*
******************************************************************************/
#define Xil_AssertNonvoidAlways() \
{ \
Xil_Assert(__FILE__, __LINE__); \
Xil_AssertStatus = XIL_ASSERT_OCCURRED; \
return 0; \
}
#else
#define Xil_AssertVoid(Expression)
#define Xil_AssertVoidAlways()
#define Xil_AssertNonvoid(Expression)
#define Xil_AssertNonvoidAlways()
#endif
/************************** Function Prototypes ******************************/
void Xil_AssertSetCallback(Xil_AssertCallback Routine);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_assert_apis".
*/
@@ -1,118 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_cache.h
*
* @addtogroup a9_cache_apis Cortex A9 Processor Cache Functions
*
* Cache functions provide access to cache related operations such as flush
* and invalidate for instruction and data caches. It gives option to perform
* the cache operations on a single cacheline, a range of memory and an entire
* cache.
*
* @{
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 01/29/10 First release
* 3.04a sdm 01/02/12 Remove redundant dsb/dmb instructions in cache maintenance
* APIs.
* 6.8 aru 09/06/18 Removed compilation warnings for ARMCC toolchain.
* </pre>
*
******************************************************************************/
#ifndef XIL_CACHE_H
#define XIL_CACHE_H
#include "xil_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __GNUC__
#define asm_cp15_inval_dc_line_mva_poc(param) __asm__ __volatile__("mcr " \
XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (param));
#define asm_cp15_clean_inval_dc_line_mva_poc(param) __asm__ __volatile__("mcr " \
XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (param));
#define asm_cp15_inval_ic_line_mva_pou(param) __asm__ __volatile__("mcr " \
XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (param));
#define asm_cp15_inval_dc_line_sw(param) __asm__ __volatile__("mcr " \
XREG_CP15_INVAL_DC_LINE_SW :: "r" (param));
#define asm_cp15_clean_inval_dc_line_sw(param) __asm__ __volatile__("mcr " \
XREG_CP15_CLEAN_INVAL_DC_LINE_SW :: "r" (param));
#elif defined (__ICCARM__)
#define asm_cp15_inval_dc_line_mva_poc(param) __asm volatile ("mcr " \
XREG_CP15_INVAL_DC_LINE_MVA_POC :: "r" (param));
#define asm_cp15_clean_inval_dc_line_mva_poc(param) __asm volatile ("mcr " \
XREG_CP15_CLEAN_INVAL_DC_LINE_MVA_POC :: "r" (param));
#define asm_cp15_inval_ic_line_mva_pou(param) __asm volatile ("mcr " \
XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (param));
#define asm_cp15_inval_dc_line_sw(param) __asm volatile ("mcr " \
XREG_CP15_INVAL_DC_LINE_SW :: "r" (param));
#define asm_cp15_clean_inval_dc_line_sw(param) __asm volatile ("mcr " \
XREG_CP15_CLEAN_INVAL_DC_LINE_SW :: "r" (param));
#endif
void Xil_DCacheEnable(void);
void Xil_DCacheDisable(void);
void Xil_DCacheInvalidate(void);
void Xil_DCacheInvalidateRange(INTPTR adr, u32 len);
void Xil_DCacheFlush(void);
void Xil_DCacheFlushRange(INTPTR adr, u32 len);
void Xil_ICacheEnable(void);
void Xil_ICacheDisable(void);
void Xil_ICacheInvalidate(void);
void Xil_ICacheInvalidateRange(INTPTR adr, u32 len);
#ifdef __cplusplus
}
#endif
#endif
/**
* @} End of "addtogroup a9_cache_apis".
*/
@@ -1,97 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2018 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_cache_l.h
*
* Contains L1 and L2 specific functions for the ARM cache functionality
* used by xcache.c. This functionality is being made available here for
* more sophisticated users.
*
* @addtogroup a9_cache_apis
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a ecm 01/24/10 First release
* 6.8 aru 09/06/18 Removed compilation warnings for ARMCC toolchain.
* </pre>
*
******************************************************************************/
#ifndef XIL_CACHE_MACH_H
#define XIL_CACHE_MACH_H
#include "xil_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/************************** Function Prototypes ******************************/
void Xil_DCacheInvalidateLine(u32 adr);
void Xil_DCacheFlushLine(u32 adr);
void Xil_DCacheStoreLine(u32 adr);
void Xil_ICacheInvalidateLine(u32 adr);
void Xil_L1DCacheEnable(void);
void Xil_L1DCacheDisable(void);
void Xil_L1DCacheInvalidate(void);
void Xil_L1DCacheInvalidateLine(u32 adr);
void Xil_L1DCacheInvalidateRange(u32 adr, u32 len);
void Xil_L1DCacheFlush(void);
void Xil_L1DCacheFlushLine(u32 adr);
void Xil_L1DCacheFlushRange(u32 adr, u32 len);
void Xil_L1DCacheStoreLine(u32 adr);
void Xil_L1ICacheEnable(void);
void Xil_L1ICacheDisable(void);
void Xil_L1ICacheInvalidate(void);
void Xil_L1ICacheInvalidateLine(u32 adr);
void Xil_L1ICacheInvalidateRange(u32 adr, u32 len);
void Xil_L2CacheEnable(void);
void Xil_L2CacheDisable(void);
void Xil_L2CacheInvalidate(void);
void Xil_L2CacheInvalidateLine(u32 adr);
void Xil_L2CacheInvalidateRange(u32 adr, u32 len);
void Xil_L2CacheFlush(void);
void Xil_L2CacheFlushLine(u32 adr);
void Xil_L2CacheFlushRange(u32 adr, u32 len);
void Xil_L2CacheStoreLine(u32 adr);
#ifdef __cplusplus
}
#endif
#endif
/**
* @} End of "addtogroup a9_cache_apis".
*/
@@ -1,89 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_cache_vxworks.h
*
* Contains the cache related functions for VxWorks that is wrapped by
* xil_cache.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a hbm 12/11/09 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XIL_CACHE_VXWORKS_H
#define XIL_CACHE_VXWORKS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "vxWorks.h"
#include "vxLib.h"
#include "sysLibExtra.h"
#include "cacheLib.h"
#if (CPU_FAMILY==PPC)
#define Xil_DCacheEnable() cacheEnable(DATA_CACHE)
#define Xil_DCacheDisable() cacheDisable(DATA_CACHE)
#define Xil_DCacheInvalidateRange(Addr, Len) \
cacheInvalidate(DATA_CACHE, (void *)(Addr), (Len))
#define Xil_DCacheFlushRange(Addr, Len) \
cacheFlush(DATA_CACHE, (void *)(Addr), (Len))
#define Xil_ICacheEnable() cacheEnable(INSTRUCTION_CACHE)
#define Xil_ICacheDisable() cacheDisable(INSTRUCTION_CACHE)
#define Xil_ICacheInvalidateRange(Addr, Len) \
cacheInvalidate(INSTRUCTION_CACHE, (void *)(Addr), (Len))
#else
#error "Unknown processor / architecture. Must be PPC for VxWorks."
#endif
#ifdef __cplusplus
}
#endif
#endif
@@ -1,127 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_errata.h
*
* @addtogroup a9_errata Cortex A9 Processor and pl310 Errata Support
* @{
* Various ARM errata are handled in the standalone BSP. The implementation for
* errata handling follows ARM guidelines and is based on the open source Linux
* support for these errata.
*
* @note
* The errata handling is enabled by default. To disable handling of all the
* errata globally, un-define the macro ENABLE_ARM_ERRATA in xil_errata.h. To
* disable errata on a per-erratum basis, un-define relevant macros in
* xil_errata.h.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a srt 04/18/13 First release
* 6.6 mus 12/07/17 Removed errata 753970, It fixes CR#989132.
* </pre>
*
******************************************************************************/
#ifndef XIL_ERRATA_H
#define XIL_ERRATA_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name errata_definitions
*
* The errata conditions handled in the standalone BSP are listed below
* @{
*/
#define ENABLE_ARM_ERRATA 1
#ifdef ENABLE_ARM_ERRATA
/**
* Errata No: 742230
* Description: DMB operation may be faulty
*/
#define CONFIG_ARM_ERRATA_742230 1
/**
* Errata No: 743622
* Description: Faulty hazard checking in the Store Buffer may lead
* to data corruption.
*/
#define CONFIG_ARM_ERRATA_743622 1
/**
* Errata No: 775420
* Description: A data cache maintenance operation which aborts,
* might lead to deadlock
*/
#define CONFIG_ARM_ERRATA_775420 1
/**
* Errata No: 794073
* Description: Speculative instruction fetches with MMU disabled
* might not comply with architectural requirements
*/
#define CONFIG_ARM_ERRATA_794073 1
/** PL310 L2 Cache Errata */
/**
* Errata No: 588369
* Description: Clean & Invalidate maintenance operations do not
* invalidate clean lines
*/
#define CONFIG_PL310_ERRATA_588369 1
/**
* Errata No: 727915
* Description: Background Clean and Invalidate by Way operation
* can cause data corruption
*/
#define CONFIG_PL310_ERRATA_727915 1
/*@}*/
#endif /* ENABLE_ARM_ERRATA */
#ifdef __cplusplus
}
#endif
#endif /* XIL_ERRATA_H */
/**
* @} End of "addtogroup a9_errata".
*/
@@ -1,285 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2015 - 2016 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_exception.h
*
* This header file contains ARM Cortex A53,A9,R5 specific exception related APIs.
* For exception related functions that can be used across all Xilinx supported
* processors, please use xil_exception.h.
*
* @addtogroup arm_exception_apis ARM Processor Exception Handling
* @{
* ARM processors specific exception related APIs for cortex A53,A9 and R5 can
* utilized for enabling/disabling IRQ, registering/removing handler for
* exceptions or initializing exception vector table with null handler.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------- -------- -----------------------------------------------
* 5.2 pkp 28/05/15 First release
* 6.0 mus 27/07/16 Consolidated file for a53,a9 and r5 processors
* 6.7 mna 26/04/18 Add API Xil_GetExceptionRegisterHandler.
* 6.7 asa 18/05/18 Update signature of API Xil_GetExceptionRegisterHandler.
* 7.0 mus 01/03/19 Tweak Xil_ExceptionEnableMask and
* Xil_ExceptionDisableMask macros to support legacy
* examples for Cortexa72 EL3 exception level.
* </pre>
*
******************************************************************************/
#ifndef XIL_EXCEPTION_H /* prevent circular inclusions */
#define XIL_EXCEPTION_H /* by using protection macros */
/***************************** Include Files ********************************/
#include "xil_types.h"
#include "xpseudo_asm.h"
#include "bspconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
/************************** Constant Definitions ****************************/
#define XIL_EXCEPTION_FIQ XREG_CPSR_FIQ_ENABLE
#define XIL_EXCEPTION_IRQ XREG_CPSR_IRQ_ENABLE
#define XIL_EXCEPTION_ALL (XREG_CPSR_FIQ_ENABLE | XREG_CPSR_IRQ_ENABLE)
#define XIL_EXCEPTION_ID_FIRST 0U
#if defined (__aarch64__)
#define XIL_EXCEPTION_ID_SYNC_INT 1U
#define XIL_EXCEPTION_ID_IRQ_INT 2U
#define XIL_EXCEPTION_ID_FIQ_INT 3U
#define XIL_EXCEPTION_ID_SERROR_ABORT_INT 4U
#define XIL_EXCEPTION_ID_LAST 5U
#else
#define XIL_EXCEPTION_ID_RESET 0U
#define XIL_EXCEPTION_ID_UNDEFINED_INT 1U
#define XIL_EXCEPTION_ID_SWI_INT 2U
#define XIL_EXCEPTION_ID_PREFETCH_ABORT_INT 3U
#define XIL_EXCEPTION_ID_DATA_ABORT_INT 4U
#define XIL_EXCEPTION_ID_IRQ_INT 5U
#define XIL_EXCEPTION_ID_FIQ_INT 6U
#define XIL_EXCEPTION_ID_LAST 6U
#endif
/*
* XIL_EXCEPTION_ID_INT is defined for all Xilinx processors.
*/
#if defined (versal) && !defined(ARMR5) && EL3
#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_FIQ_INT
#else
#define XIL_EXCEPTION_ID_INT XIL_EXCEPTION_ID_IRQ_INT
#endif
/**************************** Type Definitions ******************************/
/**
* This typedef is the exception handler function.
*/
typedef void (*Xil_ExceptionHandler)(void *data);
typedef void (*Xil_InterruptHandler)(void *data);
/***************** Macros (Inline Functions) Definitions ********************/
/****************************************************************************/
/**
* @brief Enable Exceptions.
*
* @param Mask: Value for enabling the exceptions.
*
* @return None.
*
* @note If bit is 0, exception is enabled.
* C-Style signature: void Xil_ExceptionEnableMask(Mask)
*
******************************************************************************/
#if defined (versal) && !defined(ARMR5) && EL3
/*
* Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports
* only FIQ at EL3. Hence, tweaking this macro to always enable FIQ
* ignoring argument passed by user.
*/
#define Xil_ExceptionEnableMask(Mask) \
mtcpsr(mfcpsr() & ~ ((XIL_EXCEPTION_FIQ) & XIL_EXCEPTION_ALL))
#elif defined (__GNUC__) || defined (__ICCARM__)
#define Xil_ExceptionEnableMask(Mask) \
mtcpsr(mfcpsr() & ~ ((Mask) & XIL_EXCEPTION_ALL))
#else
#define Xil_ExceptionEnableMask(Mask) \
{ \
register u32 Reg __asm("cpsr"); \
mtcpsr((Reg) & (~((Mask) & XIL_EXCEPTION_ALL))); \
}
#endif
/****************************************************************************/
/**
* @brief Enable the IRQ exception.
*
* @return None.
*
* @note None.
*
******************************************************************************/
#if defined (versal) && !defined(ARMR5) && EL3
#define Xil_ExceptionEnable() \
Xil_ExceptionEnableMask(XIL_EXCEPTION_FIQ)
#else
#define Xil_ExceptionEnable() \
Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ)
#endif
/****************************************************************************/
/**
* @brief Disable Exceptions.
*
* @param Mask: Value for disabling the exceptions.
*
* @return None.
*
* @note If bit is 1, exception is disabled.
* C-Style signature: Xil_ExceptionDisableMask(Mask)
*
******************************************************************************/
#if defined (versal) && !defined(ARMR5) && EL3
/*
* Cortexa72 processor in versal is coupled with GIC-500, and GIC-500 supports
* only FIQ at EL3. Hence, tweaking this macro to always disable FIQ
* ignoring argument passed by user.
*/
#define Xil_ExceptionDisableMask(Mask) \
mtcpsr(mfcpsr() | ((XIL_EXCEPTION_FIQ) & XIL_EXCEPTION_ALL))
#elif defined (__GNUC__) || defined (__ICCARM__)
#define Xil_ExceptionDisableMask(Mask) \
mtcpsr(mfcpsr() | ((Mask) & XIL_EXCEPTION_ALL))
#else
#define Xil_ExceptionDisableMask(Mask) \
{ \
register u32 Reg __asm("cpsr"); \
mtcpsr((Reg) | ((Mask) & XIL_EXCEPTION_ALL)); \
}
#endif
/****************************************************************************/
/**
* Disable the IRQ exception.
*
* @return None.
*
* @note None.
*
******************************************************************************/
#define Xil_ExceptionDisable() \
Xil_ExceptionDisableMask(XIL_EXCEPTION_IRQ)
#if !defined (__aarch64__) && !defined (ARMA53_32)
/****************************************************************************/
/**
* @brief Enable nested interrupts by clearing the I and F bits in CPSR. This
* API is defined for cortex-a9 and cortex-r5.
*
* @return None.
*
* @note This macro is supposed to be used from interrupt handlers. In the
* interrupt handler the interrupts are disabled by default (I and F
* are 1). To allow nesting of interrupts, this macro should be
* used. It clears the I and F bits by changing the ARM mode to
* system mode. Once these bits are cleared and provided the
* preemption of interrupt conditions are met in the GIC, nesting of
* interrupts will start happening.
* Caution: This macro must be used with caution. Before calling this
* macro, the user must ensure that the source of the current IRQ
* is appropriately cleared. Otherwise, as soon as we clear the I and
* F bits, there can be an infinite loop of interrupts with an
* eventual crash (all the stack space getting consumed).
******************************************************************************/
#define Xil_EnableNestedInterrupts() \
__asm__ __volatile__ ("stmfd sp!, {lr}"); \
__asm__ __volatile__ ("mrs lr, spsr"); \
__asm__ __volatile__ ("stmfd sp!, {lr}"); \
__asm__ __volatile__ ("msr cpsr_c, #0x1F"); \
__asm__ __volatile__ ("stmfd sp!, {lr}");
/****************************************************************************/
/**
* @brief Disable the nested interrupts by setting the I and F bits. This API
* is defined for cortex-a9 and cortex-r5.
*
* @return None.
*
* @note This macro is meant to be called in the interrupt service routines.
* This macro cannot be used independently. It can only be used when
* nesting of interrupts have been enabled by using the macro
* Xil_EnableNestedInterrupts(). In a typical flow, the user first
* calls the Xil_EnableNestedInterrupts in the ISR at the appropriate
* point. The user then must call this macro before exiting the interrupt
* service routine. This macro puts the ARM back in IRQ/FIQ mode and
* hence sets back the I and F bits.
******************************************************************************/
#define Xil_DisableNestedInterrupts() \
__asm__ __volatile__ ("ldmfd sp!, {lr}"); \
__asm__ __volatile__ ("msr cpsr_c, #0x92"); \
__asm__ __volatile__ ("ldmfd sp!, {lr}"); \
__asm__ __volatile__ ("msr spsr_cxsf, lr"); \
__asm__ __volatile__ ("ldmfd sp!, {lr}"); \
#endif
/************************** Variable Definitions ****************************/
/************************** Function Prototypes *****************************/
extern void Xil_ExceptionRegisterHandler(u32 Exception_id,
Xil_ExceptionHandler Handler,
void *Data);
extern void Xil_ExceptionRemoveHandler(u32 Exception_id);
extern void Xil_GetExceptionRegisterHandler(u32 Exception_id,
Xil_ExceptionHandler *Handler, void **Data);
extern void Xil_ExceptionInit(void);
#if defined (__aarch64__)
void Xil_SyncAbortHandler(void *CallBackRef);
void Xil_SErrorAbortHandler(void *CallBackRef);
#else
extern void Xil_DataAbortHandler(void *CallBackRef);
extern void Xil_PrefetchAbortHandler(void *CallBackRef);
extern void Xil_UndefinedExceptionHandler(void *CallBackRef);
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XIL_EXCEPTION_H */
/**
* @} End of "addtogroup arm_exception_apis".
*/
@@ -1,65 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_hal.h
*
* Contains all the HAL header files.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a hbm 07/28/09 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XIL_HAL_H
#define XIL_HAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "xil_cache.h"
#include "xil_io.h"
#include "xil_assert.h"
#include "xil_exception.h"
#include "xil_types.h"
#ifdef __cplusplus
}
#endif
#endif
@@ -1,341 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2014 - 2016 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_io.h
*
* @addtogroup common_io_interfacing_apis Register IO interfacing APIs
*
* The xil_io.h file contains the interface for the general I/O component, which
* encapsulates the Input/Output functions for the processors that do not
* require any special I/O handling.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------- -------- -----------------------------------------------
* 5.00 pkp 05/29/14 First release
* 6.00 mus 08/19/16 Remove checking of __LITTLE_ENDIAN__ flag for
* ARM processors
* </pre>
******************************************************************************/
#ifndef XIL_IO_H /* prevent circular inclusions */
#define XIL_IO_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_printf.h"
#if defined (__MICROBLAZE__)
#include "mb_interface.h"
#else
#include "xpseudo_asm.h"
#endif
/************************** Function Prototypes ******************************/
u16 Xil_EndianSwap16(u16 Data);
u32 Xil_EndianSwap32(u32 Data);
#ifdef ENABLE_SAFETY
extern u32 XStl_RegUpdate(u32 RegAddr, u32 RegVal);
#endif
/***************** Macros (Inline Functions) Definitions *********************/
#if defined __GNUC__
#if defined (__MICROBLAZE__)
# define INST_SYNC mbar(0)
# define DATA_SYNC mbar(1)
# else
# define SYNCHRONIZE_IO dmb()
# define INST_SYNC isb()
# define DATA_SYNC dsb()
# endif
#else
# define SYNCHRONIZE_IO
# define INST_SYNC
# define DATA_SYNC
# define INST_SYNC
# define DATA_SYNC
#endif
#if defined (__GNUC__) || defined (__ICCARM__) || defined (__MICROBLAZE__)
#define INLINE inline
#else
#define INLINE __inline
#endif
/*****************************************************************************/
/**
*
* @brief Performs an input operation for a memory location by reading
* from the specified address and returning the 8 bit Value read from
* that address.
*
* @param Addr: contains the address to perform the input operation
*
* @return The 8 bit Value read from the specified input address.
*
******************************************************************************/
static INLINE u8 Xil_In8(UINTPTR Addr)
{
return *(volatile u8 *) Addr;
}
/*****************************************************************************/
/**
*
* @brief Performs an input operation for a memory location by reading from
* the specified address and returning the 16 bit Value read from that
* address.
*
* @param Addr: contains the address to perform the input operation
*
* @return The 16 bit Value read from the specified input address.
*
******************************************************************************/
static INLINE u16 Xil_In16(UINTPTR Addr)
{
return *(volatile u16 *) Addr;
}
/*****************************************************************************/
/**
*
* @brief Performs an input operation for a memory location by
* reading from the specified address and returning the 32 bit Value
* read from that address.
*
* @param Addr: contains the address to perform the input operation
*
* @return The 32 bit Value read from the specified input address.
*
******************************************************************************/
static INLINE u32 Xil_In32(UINTPTR Addr)
{
return *(volatile u32 *) Addr;
}
/*****************************************************************************/
/**
*
* @brief Performs an input operation for a memory location by reading the
* 64 bit Value read from that address.
*
*
* @param Addr: contains the address to perform the input operation
*
* @return The 64 bit Value read from the specified input address.
*
******************************************************************************/
static INLINE u64 Xil_In64(UINTPTR Addr)
{
return *(volatile u64 *) Addr;
}
/*****************************************************************************/
/**
*
* @brief Performs an output operation for an memory location by
* writing the 8 bit Value to the the specified address.
*
* @param Addr: contains the address to perform the output operation
* @param Value: contains the 8 bit Value to be written at the specified
* address.
*
* @return None.
*
******************************************************************************/
static INLINE void Xil_Out8(UINTPTR Addr, u8 Value)
{
volatile u8 *LocalAddr = (volatile u8 *)Addr;
*LocalAddr = Value;
}
/*****************************************************************************/
/**
*
* @brief Performs an output operation for a memory location by writing the
* 16 bit Value to the the specified address.
*
* @param Addr contains the address to perform the output operation
* @param Value contains the Value to be written at the specified address.
*
* @return None.
*
******************************************************************************/
static INLINE void Xil_Out16(UINTPTR Addr, u16 Value)
{
volatile u16 *LocalAddr = (volatile u16 *)Addr;
*LocalAddr = Value;
}
/*****************************************************************************/
/**
*
* @brief Performs an output operation for a memory location by writing the
* 32 bit Value to the the specified address.
*
* @param Addr contains the address to perform the output operation
* @param Value contains the 32 bit Value to be written at the specified
* address.
*
* @return None.
*
******************************************************************************/
static INLINE void Xil_Out32(UINTPTR Addr, u32 Value)
{
#ifndef ENABLE_SAFETY
volatile u32 *LocalAddr = (volatile u32 *)Addr;
*LocalAddr = Value;
#else
XStl_RegUpdate(Addr, Value);
#endif
}
/*****************************************************************************/
/**
*
* @brief Performs an output operation for a memory location by writing the
* 64 bit Value to the the specified address.
*
* @param Addr contains the address to perform the output operation
* @param Value contains 64 bit Value to be written at the specified address.
*
* @return None.
*
******************************************************************************/
static INLINE void Xil_Out64(UINTPTR Addr, u64 Value)
{
volatile u64 *LocalAddr = (volatile u64 *)Addr;
*LocalAddr = Value;
}
#if defined (__MICROBLAZE__)
#ifdef __LITTLE_ENDIAN__
# define Xil_In16LE Xil_In16
# define Xil_In32LE Xil_In32
# define Xil_Out16LE Xil_Out16
# define Xil_Out32LE Xil_Out32
# define Xil_Htons Xil_EndianSwap16
# define Xil_Htonl Xil_EndianSwap32
# define Xil_Ntohs Xil_EndianSwap16
# define Xil_Ntohl Xil_EndianSwap32
# else
# define Xil_In16BE Xil_In16
# define Xil_In32BE Xil_In32
# define Xil_Out16BE Xil_Out16
# define Xil_Out32BE Xil_Out32
# define Xil_Htons(Data) (Data)
# define Xil_Htonl(Data) (Data)
# define Xil_Ntohs(Data) (Data)
# define Xil_Ntohl(Data) (Data)
#endif
#else
# define Xil_In16LE Xil_In16
# define Xil_In32LE Xil_In32
# define Xil_Out16LE Xil_Out16
# define Xil_Out32LE Xil_Out32
# define Xil_Htons Xil_EndianSwap16
# define Xil_Htonl Xil_EndianSwap32
# define Xil_Ntohs Xil_EndianSwap16
# define Xil_Ntohl Xil_EndianSwap32
#endif
#if defined (__MICROBLAZE__)
#ifdef __LITTLE_ENDIAN__
static INLINE u16 Xil_In16BE(UINTPTR Addr)
#else
static INLINE u16 Xil_In16LE(UINTPTR Addr)
#endif
#else
static INLINE u16 Xil_In16BE(UINTPTR Addr)
#endif
{
u16 value = Xil_In16(Addr);
return Xil_EndianSwap16(value);
}
#if defined (__MICROBLAZE__)
#ifdef __LITTLE_ENDIAN__
static INLINE u32 Xil_In32BE(UINTPTR Addr)
#else
static INLINE u32 Xil_In32LE(UINTPTR Addr)
#endif
#else
static INLINE u32 Xil_In32BE(UINTPTR Addr)
#endif
{
u32 value = Xil_In32(Addr);
return Xil_EndianSwap32(value);
}
#if defined (__MICROBLAZE__)
#ifdef __LITTLE_ENDIAN__
static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value)
#else
static INLINE void Xil_Out16LE(UINTPTR Addr, u16 Value)
#endif
#else
static INLINE void Xil_Out16BE(UINTPTR Addr, u16 Value)
#endif
{
Value = Xil_EndianSwap16(Value);
Xil_Out16(Addr, Value);
}
#if defined (__MICROBLAZE__)
#ifdef __LITTLE_ENDIAN__
static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value)
#else
static INLINE void Xil_Out32LE(UINTPTR Addr, u32 Value)
#endif
#else
static INLINE void Xil_Out32BE(UINTPTR Addr, u32 Value)
#endif
{
Value = Xil_EndianSwap32(Value);
Xil_Out32(Addr, Value);
}
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_io_interfacing_apis".
*/
File diff suppressed because it is too large Load Diff
@@ -1,68 +0,0 @@
/******************************************************************************/
/**
* Copyright (C) 2015 - 2019 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/****************************************************************************/
/**
* @file xil_mem.h
*
* @addtogroup common_mem_operation_api Customized APIs for Memory Operations
*
* The xil_mem.h file contains prototype for functions related
* to memory operations. These APIs are applicable for all processors supported
* by Xilinx.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- -------- -------- -----------------------------------------------
* 6.1 nsk 11/07/16 First release.
* 7.0 mus 01/07/19 Add cpp extern macro
*
* </pre>
*
*****************************************************************************/
#ifndef XIL_MEM_H /* prevent circular inclusions */
#define XIL_MEM_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/************************** Function Prototypes *****************************/
void Xil_MemCpy(void* dst, const void* src, u32 cnt);
#ifdef __cplusplus
}
#endif
#endif /* XIL_MEM_H */
/**
* @} End of "addtogroup common_mem_operation_api".
*/
@@ -1,273 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xil_misc_psreset_api.h
*
* This file contains the various register defintions and function prototypes for
* implementing the reset functionality of zynq ps devices
*
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00b kpc 03/07/13 First release.
* </pre>
*
******************************************************************************/
#ifndef XIL_MISC_RESET_H /* prevent circular inclusions */
#define XIL_MISC_RESET_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xil_io.h"
/************************** Constant Definitions *****************************/
#define XDDRC_CTRL_BASEADDR 0xF8006000U
#define XSLCR_BASEADDR 0xF8000000U
/**< OCM configuration register */
#define XSLCR_OCM_CFG_ADDR (XSLCR_BASEADDR + 0x00000910U)
/**< SLCR unlock register */
#define XSLCR_UNLOCK_ADDR (XSLCR_BASEADDR + 0x00000008U)
/**< SLCR GEM0 rx clock control register */
#define XSLCR_GEM0_RCLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000138U)
/**< SLCR GEM1 rx clock control register */
#define XSLCR_GEM1_RCLK_CTRL_ADDR (XSLCR_BASEADDR + 0x0000013CU)
/**< SLCR GEM0 clock control register */
#define XSLCR_GEM0_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000140U)
/**< SLCR GEM1 clock control register */
#define XSLCR_GEM1_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000144U)
/**< SLCR SMC clock control register */
#define XSLCR_SMC_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000148U)
/**< SLCR GEM reset control register */
#define XSLCR_GEM_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000214U)
/**< SLCR USB0 clock control register */
#define XSLCR_USB0_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000130U)
/**< SLCR USB1 clock control register */
#define XSLCR_USB1_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000134U)
/**< SLCR USB1 reset control register */
#define XSLCR_USB_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000210U)
/**< SLCR SMC reset control register */
#define XSLCR_SMC_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000234U)
/**< SLCR Level shifter enable register */
#define XSLCR_LVL_SHFTR_EN_ADDR (XSLCR_BASEADDR + 0x00000900U)
/**< SLCR ARM pll control register */
#define XSLCR_ARM_PLL_CTRL_ADDR (XSLCR_BASEADDR + 0x00000100U)
/**< SLCR DDR pll control register */
#define XSLCR_DDR_PLL_CTRL_ADDR (XSLCR_BASEADDR + 0x00000104U)
/**< SLCR IO pll control register */
#define XSLCR_IO_PLL_CTRL_ADDR (XSLCR_BASEADDR + 0x00000108U)
/**< SLCR ARM pll configuration register */
#define XSLCR_ARM_PLL_CFG_ADDR (XSLCR_BASEADDR + 0x00000110U)
/**< SLCR DDR pll configuration register */
#define XSLCR_DDR_PLL_CFG_ADDR (XSLCR_BASEADDR + 0x00000114U)
/**< SLCR IO pll configuration register */
#define XSLCR_IO_PLL_CFG_ADDR (XSLCR_BASEADDR + 0x00000118U)
/**< SLCR ARM clock control register */
#define XSLCR_ARM_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000120U)
/**< SLCR DDR clock control register */
#define XSLCR_DDR_CLK_CTRL_ADDR (XSLCR_BASEADDR + 0x00000124U)
/**< SLCR MIO pin address register */
#define XSLCR_MIO_PIN_00_ADDR (XSLCR_BASEADDR + 0x00000700U)
/**< SLCR DMAC reset control address register */
#define XSLCR_DMAC_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x0000020CU)
/**< SLCR USB reset control address register */
/*#define XSLCR_USB_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000210U)*/
/**< SLCR GEM reset control address register */
/*#define XSLCR_GEM_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000214U)*/
/**< SLCR SDIO reset control address register */
#define XSLCR_SDIO_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000218U)
/**< SLCR SPI reset control address register */
#define XSLCR_SPI_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x0000021CU)
/**< SLCR CAN reset control address register */
#define XSLCR_CAN_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000220U)
/**< SLCR I2C reset control address register */
#define XSLCR_I2C_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000224U)
/**< SLCR UART reset control address register */
#define XSLCR_UART_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000228U)
/**< SLCR GPIO reset control address register */
#define XSLCR_GPIO_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x0000022CU)
/**< SLCR LQSPI reset control address register */
#define XSLCR_LQSPI_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000230U)
/**< SLCR SMC reset control address register */
/*#define XSLCR_SMC_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000234U)*/
/**< SLCR OCM reset control address register */
#define XSLCR_OCM_RST_CTRL_ADDR (XSLCR_BASEADDR + 0x00000238U)
/**< SMC mem controller clear config register */
#define XSMC_MEMC_CLR_CONFIG_OFFSET 0x0000000CU
/**< SMC idlecount configuration register */
#define XSMC_REFRESH_PERIOD_0_OFFSET 0x00000020U
#define XSMC_REFRESH_PERIOD_1_OFFSET 0x00000024U
/**< SMC ECC configuration register */
#define XSMC_ECC_MEMCFG1_OFFSET 0x00000404U
/**< SMC ECC command 1 register */
#define XSMC_ECC_MEMCMD1_OFFSET 0x00000404U
/**< SMC ECC command 2 register */
#define XSMC_ECC_MEMCMD2_OFFSET 0x00000404U
/**< SLCR unlock code */
#define XSLCR_UNLOCK_CODE 0x0000DF0DU
/**< SMC mem clear configuration mask */
#define XSMC_MEMC_CLR_CONFIG_MASK 0x000005FU
/**< SMC ECC memconfig 1 reset value */
#define XSMC_ECC_MEMCFG1_RESET_VAL 0x0000043U
/**< SMC ECC memcommand 1 reset value */
#define XSMC_ECC_MEMCMD1_RESET_VAL 0x01300080U
/**< SMC ECC memcommand 2 reset value */
#define XSMC_ECC_MEMCMD2_RESET_VAL 0x01E00585U
/**< DDR controller reset bit mask */
#define XDDRPS_CTRL_RESET_MASK 0x00000001U
/**< SLCR OCM configuration reset value*/
#define XSLCR_OCM_CFG_RESETVAL 0x00000008U
/**< SLCR OCM bank selection mask*/
#define XSLCR_OCM_CFG_HIADDR_MASK 0x0000000FU
/**< SLCR level shifter enable mask*/
#define XSLCR_LVL_SHFTR_EN_MASK 0x0000000FU
/**< SLCR PLL register reset values */
#define XSLCR_ARM_PLL_CTRL_RESET_VAL 0x0001A008U
#define XSLCR_DDR_PLL_CTRL_RESET_VAL 0x0001A008U
#define XSLCR_IO_PLL_CTRL_RESET_VAL 0x0001A008U
#define XSLCR_ARM_PLL_CFG_RESET_VAL 0x00177EA0U
#define XSLCR_DDR_PLL_CFG_RESET_VAL 0x00177EA0U
#define XSLCR_IO_PLL_CFG_RESET_VAL 0x00177EA0U
#define XSLCR_ARM_CLK_CTRL_RESET_VAL 0x1F000400U
#define XSLCR_DDR_CLK_CTRL_RESET_VAL 0x18400003U
/**< SLCR MIO register default values */
#define XSLCR_MIO_PIN_00_RESET_VAL 0x00001601U
#define XSLCR_MIO_PIN_02_RESET_VAL 0x00000601U
/**< SLCR Reset control registers default values */
#define XSLCR_DMAC_RST_CTRL_VAL 0x00000001U
#define XSLCR_GEM_RST_CTRL_VAL 0x000000F3U
#define XSLCR_USB_RST_CTRL_VAL 0x00000003U
#define XSLCR_I2C_RST_CTRL_VAL 0x00000003U
#define XSLCR_SPI_RST_CTRL_VAL 0x0000000FU
#define XSLCR_UART_RST_CTRL_VAL 0x0000000FU
#define XSLCR_QSPI_RST_CTRL_VAL 0x00000003U
#define XSLCR_GPIO_RST_CTRL_VAL 0x00000001U
#define XSLCR_SMC_RST_CTRL_VAL 0x00000003U
#define XSLCR_OCM_RST_CTRL_VAL 0x00000001U
#define XSLCR_SDIO_RST_CTRL_VAL 0x00000033U
#define XSLCR_CAN_RST_CTRL_VAL 0x00000003U
/**************************** Type Definitions *******************************/
/* the following data type is used to hold a null terminated version string
* consisting of the following format, "X.YYX"
*/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/*
* Performs reset operation to the ddr interface
*/
void XDdr_ResetHw(void);
/*
* Map the ocm region to post bootrom state
*/
void XOcm_Remap(void);
/*
* Performs the smc interface reset
*/
void XSmc_ResetHw(u32 BaseAddress);
/*
* updates the MIO registers with reset values
*/
void XSlcr_MioWriteResetValues(void);
/*
* updates the PLL and clock registers with reset values
*/
void XSlcr_PllWriteResetValues(void);
/*
* Disables the level shifters
*/
void XSlcr_DisableLevelShifters(void);
/*
* provides softreset to the GPIO interface
*/
void XSlcr_GpioPsReset(void);
/*
* provides softreset to the DMA interface
*/
void XSlcr_DmaPsReset(void);
/*
* provides softreset to the SMC interface
*/
void XSlcr_SmcPsReset(void);
/*
* provides softreset to the CAN interface
*/
void XSlcr_CanPsReset(void);
/*
* provides softreset to the Uart interface
*/
void XSlcr_UartPsReset(void);
/*
* provides softreset to the I2C interface
*/
void XSlcr_I2cPsReset(void);
/*
* provides softreset to the SPI interface
*/
void XSlcr_SpiPsReset(void);
/*
* provides softreset to the QSPI interface
*/
void XSlcr_QspiPsReset(void);
/*
* provides softreset to the USB interface
*/
void XSlcr_UsbPsReset(void);
/*
* provides softreset to the GEM interface
*/
void XSlcr_EmacPsReset(void);
/*
* provides softreset to the OCM interface
*/
void XSlcr_OcmReset(void);
#ifdef __cplusplus
}
#endif
#endif /* XIL_MISC_RESET_H */
@@ -1,106 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2012 - 2018 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
* @file xil_mmu.h
*
* @addtogroup a9_mmu_apis Cortex A9 Processor MMU Functions
*
* MMU functions equip users to enable MMU, disable MMU and modify default
* memory attributes of MMU table as per the need.
*
* @{
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- ---------------------------------------------------
* 1.00a sdm 01/12/12 Initial version
* 4.2 pkp 07/21/14 Included xil_types.h file which contains definition for
* u32 which resolves issue of CR#805869
* 5.4 pkp 23/11/15 Added attribute definitions for Xil_SetTlbAttributes API
* 6.8 aru 09/06/18 Removed compilation warnings for ARMCC toolchain.
* </pre>
*
*
******************************************************************************/
#ifndef XIL_MMU_H
#define XIL_MMU_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/***************************** Include Files *********************************/
#include "xil_types.h"
/***************** Macros (Inline Functions) Definitions *********************/
/**************************** Type Definitions *******************************/
/************************** Constant Definitions *****************************/
/* Memory type */
#define NORM_NONCACHE 0x11DE2 /* Normal Non-cacheable */
#define STRONG_ORDERED 0xC02 /* Strongly ordered */
#define DEVICE_MEMORY 0xC06 /* Device memory */
#define RESERVED 0x0 /* reserved memory */
/* Normal write-through cacheable shareable */
#define NORM_WT_CACHE 0x16DEA
/* Normal write back cacheable shareable */
#define NORM_WB_CACHE 0x15DE6
/* shareability attribute */
#define SHAREABLE (0x1 << 16)
#define NON_SHAREABLE (~(0x1 << 16))
/* Execution type */
#define EXECUTE_NEVER ((0x1 << 4) | (0x1 << 0))
/************************** Variable Definitions *****************************/
/************************** Function Prototypes ******************************/
void Xil_SetTlbAttributes(INTPTR Addr, u32 attrib);
void Xil_EnableMMU(void);
void Xil_DisableMMU(void);
void* Xil_MemMap(UINTPTR PhysAddr, size_t size, u32 flags);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* XIL_MMU_H */
/**
* @} End of "addtogroup a9_mmu_apis".
*/
@@ -1,48 +0,0 @@
#ifndef XIL_PRINTF_H
#define XIL_PRINTF_H
#ifdef __cplusplus
extern "C" {
#endif
#include <ctype.h>
#include <string.h>
#include <stdarg.h>
#include "xil_types.h"
#include "xparameters.h"
#include "bspconfig.h"
#if defined (__aarch64__) && HYP_GUEST && EL1_NONSECURE && XEN_USE_PV_CONSOLE
#include "xen_console.h"
#endif
/*----------------------------------------------------*/
/* Use the following parameter passing structure to */
/* make xil_printf re-entrant. */
/*----------------------------------------------------*/
struct params_s;
/*---------------------------------------------------*/
/* The purpose of this routine is to output data the */
/* same as the standard printf function without the */
/* overhead most run-time libraries involve. Usually */
/* the printf brings in many kilobytes of code and */
/* that is unacceptable in most embedded systems. */
/*---------------------------------------------------*/
typedef char8* charptr;
typedef s32 (*func_ptr)(int c);
/* */
void xil_printf( const char8 *ctrl1, ...);
void print( const char8 *ptr);
extern void outbyte (char8 c);
extern char8 inbyte(void);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
@@ -1,128 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2017 - 2019 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_sleeptimer.h
*
* This header file contains ARM Cortex A53,A9,R5 specific sleep related APIs.
* For sleep related functions that can be used across all Xilinx supported
* processors, please use xil_sleeptimer.h.
*
*
* <pre>
* MODIFICATION HISTORY :
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 6.6 srm 10/18/17 First Release.
* 7.0 mus 01/07/19 Add cpp extern macro
*
* </pre>
*****************************************************************************/
#ifndef XIL_SLEEPTIMER_H /* prevent circular inclusions */
#define XIL_SLEEPTIMER_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/**************************** Include Files ********************************/
#include "xil_io.h"
#include "xparameters.h"
#include "bspconfig.h"
/************************** Constant Definitions *****************************/
#if defined (ARMR5) || (__aarch64__) || (ARMA53_32)
#define XSLEEP_TIMER_REG_SHIFT 32U
#define XSleep_ReadCounterVal Xil_In32
#define XCntrVal u32
#else
#define XSLEEP_TIMER_REG_SHIFT 16U
#define XSleep_ReadCounterVal Xil_In16
#define XCntrVal u16
#endif
#if defined(ARMR5) || (defined (__aarch64__) && EL3==1) || defined (ARMA53_32)
#if defined (versal)
#define CRL_TTC_RST 0xFF5E0344U
#define CRL_TTC_BASE_RST_MASK 0x1U
#else
#define RST_LPD_IOU2 0xFF5E0238U
#define RST_LPD_IOU2_TTC_BASE_RESET_MASK 0x00000800U
#endif
#endif
#if defined (SLEEP_TIMER_BASEADDR)
/** @name Register Map
*
* Register offsets from the base address of the TTC device
*
* @{
*/
#define XSLEEP_TIMER_TTC_CLK_CNTRL_OFFSET 0x00000000U
/**< Clock Control Register */
#define XSLEEP_TIMER_TTC_CNT_CNTRL_OFFSET 0x0000000CU
/**< Counter Control Register*/
#define XSLEEP_TIMER_TTC_COUNT_VALUE_OFFSET 0x00000018U
/**< Current Counter Value */
/* @} */
/** @name Clock Control Register
* Clock Control Register definitions of TTC
* @{
*/
#define XSLEEP_TIMER_TTC_CLK_CNTRL_PS_EN_MASK 0x00000001U
/**< Prescale enable */
/* @} */
/** @name Counter Control Register
* Counter Control Register definitions of TTC
* @{
*/
#define XSLEEP_TIMER_TTC_CNT_CNTRL_DIS_MASK 0x00000001U
/**< Disable the counter */
#define XSLEEP_TIMER_TTC_CNT_CNTRL_RST_MASK 0x00000010U
/**< Reset counter */
/* @} */
/**************************** Type Definitions *******************************/
/************************** Function Prototypes ******************************/
void Xil_SleepTTCCommon(u32 delay, u64 frequency);
void XTime_StartTTCTimer();
#endif
#ifdef __cplusplus
}
#endif
#endif /* XIL_SLEEPTIMER_H */
@@ -1,67 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_testcache.h
*
* @addtogroup common_test_utils
* <h2>Cache test </h2>
* The xil_testcache.h file contains utility functions to test cache.
*
* @{
* <pre>
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a hbm 07/29/09 First release
* </pre>
*
******************************************************************************/
#ifndef XIL_TESTCACHE_H /* prevent circular inclusions */
#define XIL_TESTCACHE_H /* by using protection macros */
#include "xil_types.h"
#ifdef __cplusplus
extern "C" {
#endif
extern s32 Xil_TestDCacheRange(void);
extern s32 Xil_TestDCacheAll(void);
extern s32 Xil_TestICacheRange(void);
extern s32 Xil_TestICacheAll(void);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_test_utils".
*/
@@ -1,90 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_testio.h
*
* @addtogroup common_test_utils Test Utilities
* <h2>I/O test </h2>
* The xil_testio.h file contains utility functions to test endian related memory
* IO functions.
*
* A subset of the memory tests can be selected or all of the tests can be run
* in order. If there is an error detected by a subtest, the test stops and the
* failure code is returned. Further tests are not run even if all of the tests
* are selected.
*
* @{
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00 hbm 08/05/09 First release
* </pre>
*
******************************************************************************/
#ifndef XIL_TESTIO_H /* prevent circular inclusions */
#define XIL_TESTIO_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
/************************** Constant Definitions *****************************/
#define XIL_TESTIO_DEFAULT 0
#define XIL_TESTIO_LE 1
#define XIL_TESTIO_BE 2
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
extern s32 Xil_TestIO8(u8 *Addr, s32 Length, u8 Value);
extern s32 Xil_TestIO16(u16 *Addr, s32 Length, u16 Value, s32 Kind, s32 Swap);
extern s32 Xil_TestIO32(u32 *Addr, s32 Length, u32 Value, s32 Kind, s32 Swap);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_test_utils".
*/
@@ -1,154 +0,0 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xil_testmem.h
* @addtogroup common_test_utils
*
* <h2>Memory test</h2>
*
* The xil_testmem.h file contains utility functions to test memory.
* A subset of the memory tests can be selected or all of the tests can be run
* in order. If there is an error detected by a subtest, the test stops and the
* failure code is returned. Further tests are not run even if all of the tests
* are selected.
* Following list describes the supported memory tests:
*
* - XIL_TESTMEM_ALLMEMTESTS: This test runs all of the subtests.
*
* - XIL_TESTMEM_INCREMENT: This test
* starts at 'XIL_TESTMEM_INIT_VALUE' and uses the incrementing value as the
* test value for memory.
*
* - XIL_TESTMEM_WALKONES: Also known as the Walking ones test. This test
* uses a walking '1' as the test value for memory.
* @code
* location 1 = 0x00000001
* location 2 = 0x00000002
* ...
* @endcode
*
* - XIL_TESTMEM_WALKZEROS: Also known as the Walking zero's test.
* This test uses the inverse value of the walking ones test
* as the test value for memory.
* @code
* location 1 = 0xFFFFFFFE
* location 2 = 0xFFFFFFFD
* ...
*@endcode
*
* - XIL_TESTMEM_INVERSEADDR: Also known as the inverse address test.
* This test uses the inverse of the address of the location under test
* as the test value for memory.
*
* - XIL_TESTMEM_FIXEDPATTERN: Also known as the fixed pattern test.
* This test uses the provided patters as the test value for memory.
* If zero is provided as the pattern the test uses '0xDEADBEEF".
*
* @warning
* The tests are <b>DESTRUCTIVE</b>. Run before any initialized memory spaces
* have been set up.
* The address provided to the memory tests is not checked for
* validity except for the NULL case. It is possible to provide a code-space
* pointer for this test to start with and ultimately destroy executable code
* causing random failures.
*
* @note
* Used for spaces where the address range of the region is smaller than
* the data width. If the memory range is greater than 2 ** width,
* the patterns used in XIL_TESTMEM_WALKONES and XIL_TESTMEM_WALKZEROS will
* repeat on a boundry of a power of two making it more difficult to detect
* addressing errors. The XIL_TESTMEM_INCREMENT and XIL_TESTMEM_INVERSEADDR
* tests suffer the same problem. Ideally, if large blocks of memory are to be
* tested, break them up into smaller regions of memory to allow the test
* patterns used not to repeat over the region tested.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a hbm 08/25/09 First release
* </pre>
*
******************************************************************************/
#ifndef XIL_TESTMEM_H /* prevent circular inclusions */
#define XIL_TESTMEM_H /* by using protection macros */
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/* xutil_memtest defines */
#define XIL_TESTMEM_INIT_VALUE 1U
/** @name Memory subtests
* @{
*/
/**
* See the detailed description of the subtests in the file description.
*/
#define XIL_TESTMEM_ALLMEMTESTS 0x00U
#define XIL_TESTMEM_INCREMENT 0x01U
#define XIL_TESTMEM_WALKONES 0x02U
#define XIL_TESTMEM_WALKZEROS 0x03U
#define XIL_TESTMEM_INVERSEADDR 0x04U
#define XIL_TESTMEM_FIXEDPATTERN 0x05U
#define XIL_TESTMEM_MAXTEST XIL_TESTMEM_FIXEDPATTERN
/* @} */
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/* xutil_testmem prototypes */
extern s32 Xil_TestMem32(u32 *Addr, u32 Words, u32 Pattern, u8 Subtest);
extern s32 Xil_TestMem16(u16 *Addr, u32 Words, u16 Pattern, u8 Subtest);
extern s32 Xil_TestMem8(u8 *Addr, u32 Words, u8 Pattern, u8 Subtest);
#ifdef __cplusplus
}
#endif
#endif /* end of protection macro */
/**
* @} End of "addtogroup common_test_utils".
*/

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