Files
datalink_nc_mode/datalink814_sp/src/main.c
T
2023-12-20 00:11:03 +08:00

780 lines
24 KiB
C

/*****************************************************************************/
/**
* Description: main.c
*
* Date: 2021-11-13 13:19
* Last Edit Time: [2023-04-23 21:32]
*
* Revisions: Rev 0.0
* History:
* [2021-11-13]: Initial edition.
* [2022-03-28]: Add bit error test mode.
* [2023-04-23]: Bug fixed,
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Networking
*
******************************************************************************/
/***************************** Include Files *********************************/
// Standard
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
// Xilinx
#include "xintc.h" // The generic interrupt controller driver component
#include "xil_exception.h" // ARM Cortex A9 specific exception related APIs
#include "sleep.h" // Sleep APIs for Cortex A9
#include "xgpio.h" // GPIO APIs for Cortex A9
#include "xbram.h"
#include "xtmrctr.h"
#include "xsysmon.h"
// ADI Drivers
#include "dev_profile/dev_profile.h"
#include "adi_noos/drivers/axi_core/spi_engine/spi_engine.h"
#include "adi_noos/drivers/platform/gpio_extra.h"
// User
#include "common.h"
#include "error.h"
#include "config/app_config.h"
#include "c2c_bridge/c2c_bridge.h"
#include "phy_ctrl/phy_ctrl.h"
#include "circ_queue/circ_queue.h"
#include "inter_comm/inter_comm.h"
/************************** Function Prototypes ******************************/
int32_t SetupInterruptSystem(XIntc* instPtr, uint32_t devId);
int32_t XADC_Init(XSysMon* instPtr, uint16_t devId);
int32_t ScuTimerInit(XTmrCtr* instPtr, uint16_t devId);
// Utility functions
int32_t Intercom_C2cRecvData(void* buffPtr, int32_t dataLen);
int32_t Intercom_C2cSendData2Addr(void* buffPtr, int32_t dataLen, uint16_t subaddrId);
// IRQ Handlers
void C2c_RxIntrHandler(void* callBackRef);
void C2c_TxIntrHandler(void* callBackRef);
void Timer_IntrHandler(void* CallBackRef);
void PhyIntr_Handler(void *callBackRef);
/************************** Constant Definitions *****************************/
#define C2C_EXTRA_LEN (sizeof(C2C_EXTRA) + COMMON_CRC_LEN)
C2C_CONFIG c2cConfig = {
.capacity = C2C_BUFF_MAX,
.dmaConfig = {
.devId = C2C_AXI_DMA_DEVICE_ID,
.transMax = C2C_BUFF_MAX,
.defaultTransLen = C2C_BUFF_MAX,
.timeoutTh = 500
}
};
INTER_COMM_CONFIG intrCommConfig = {
.data_recv = Intercom_C2cRecvData,
.data_send = Intercom_C2cSendData2Addr,
.phyInstPtr = NULL
};
PHY_CONFIG phyConfig = {
.devId = 0,
.baseAddr = PHY_CTRL_BASEADDR,
.txBramId = PHY_TX_BRAM_BUFF_ID,
.rxBramId = PHY_RX_BRAM_BUFF_ID,
.antBramId = PHY_ANT_CONFIG_BRAM_ID
};
struct spi_engine_init_param spi_engine_param = {
.ref_clk_hz = SPI_ENGINE_REF_CLK,
.type = SPI_ENGINE,
.spi_engine_baseaddr = SPI_ENGINE_BASEADDR,
.cs_delay = SPI_ENGINE_CS_DELAY,
.data_width = SPI_ENGINE_DATA_WIDTH
};
struct xil_gpio_init_param xil_gpio_param = {
.type = GPIO_PS,
.device_id = GPIO_DEVICE_ID
};
/*********************** Driver Instance Definitions **************************/
static XIntc intcInst; // General interrupt controller instance
static XSysMon SysMonInst;
#ifdef GLINK_REMOTE_TEST_ENABLE
static XTmrCtr axiTimeInst; // PS scu timer
static bool isSendRemotCheckAsserted = false;//true when 1s comes
#endif
static bool isPhyUploadAsserted = false;//true when 1s comes
static CIRC_QUEUE *c2cRecvQueue;
static PHY_INST* phyInstPtr = NULL;
static INTER_COMM_INST* intrCommInstPtr = NULL;
static C2C_EXTRA* c2cExtraBuffPtr = NULL;
// For AD9361
struct ad9516_dev *ad9516_inst;
struct ad9361_reg_dev *ad9361_1_reg_inst;
struct ad9361_reg_dev *ad9361_2_reg_inst;
struct ad9361_rf_phy *ad9361_phy;
/* Helper function for AD9361 IO control*/
static int XGpio_WritePin(XGpio *InstPtr, uint32_t Channel, u32 Pin, uint8_t Value){
ASSERT(Pin <= 31 && Pin >=0 );
ASSERT(InstPtr != NULL);
ASSERT(InstPtr->IsReady == XIL_COMPONENT_IS_READY);
ASSERT((Channel == 1) || ((Channel == 2) && (InstPtr->IsDual == TRUE)));
u32 CurrValue = XGpio_DiscreteRead(InstPtr, Channel);
CurrValue = (Value == 0)? (CurrValue & (~(0x00000001 << Pin))) : (CurrValue | (0x00000001 << Pin));
XGpio_DiscreteWrite(InstPtr, Channel, CurrValue);
return SUCCESS;
}// XGpio_WritePin
/****************************************************************************/
/**
* This function dose a hardware initialization.
*
* @param None
*
* @return SUCCESS if initialize successful.
* XST_FAILURE if initialization failed.
*
*****************************************************************************/
static int Hardware_Initialize(void){
int Status;
XGpio Gpio;
Status = XGpio_Initialize(&Gpio, GPIO_DEVICE_ID);
if (Status != SUCCESS)
{
return FAILURE;
}
XGpio_SetDataDirection(&Gpio, GPIO_BANK_OUT, 0x00000000); // Bank 1 output
XGpio_SetDataDirection(&Gpio, GPIO_BANK_IN, 0xFFFFFFFF); // Bank 0 inputT_FAILURE;
/**********************************************************/
/****************** AD9516 Configuration ******************/
/**********************************************************/
Status = ad9516_init(&ad9516_inst, &ad9516_default_init_param);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9516_POWEDOWN_B, 1);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9516_SYNC_B, 1);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9516_RESET_B, 0);
mdelay(200);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9516_RESET_B, 1);
for(int i = 0; i < ad9516_default_config_len; i++){
Status = ad9516_write(ad9516_inst, ad9516_default_config[i].addr, ad9516_default_config[i].value);
if (ad9516_default_config[i].addr == 0x0000){
mdelay(500);
}
}
uint8_t rd_back;
Status = ad9516_read(ad9516_inst, 0x0003, &rd_back);
do
{
Status = ad9516_read(ad9516_inst, 0x001F, &rd_back);
}
while((rd_back & 0x01) != 0x01);
/**********************************************************/
/***************** AD9361-1 Configuration *****************/
/**********************************************************/
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_RX_FIFO_RST, 1);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_SYNC, 0);
ad9361_reg_init(&ad9361_1_reg_inst, &ad9361_1_reg_default_init_param);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_1_RESET_B, 0);
mdelay(200);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_1_RESET_B, 1);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_1_ENABLE, 0);
ad9361_reg_config(ad9361_1_reg_inst);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_1_ENABLE, 1);
/**********************************************************/
/***************** AD9361-2 Configuration *****************/
/**********************************************************/
ad9361_reg_init(&ad9361_2_reg_inst, &ad9361_2_reg_default_init_param);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_2_RESET_B, 0);
mdelay(200);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_2_RESET_B, 1);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_2_ENABLE, 0);
ad9361_reg_config(ad9361_2_reg_inst);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_2_ENABLE, 1);
// sync clock output
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9516_SYNC_B, 0);
mdelay(500);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9516_SYNC_B, 1);
// SYNC BBPLL and DIGITAL SAMPLING CLOCKS
ad9361_reg_init(&ad9361_1_reg_inst, &ad9361_1_reg_default_init_param);
ad9361_reg_init(&ad9361_2_reg_inst, &ad9361_2_reg_default_init_param);
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0D); // MCS RF Enable; MCS BBPLL Enable; MCS BB Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0D);
ad9361_reg_write(ad9361_1_reg_inst, 0x0047, 0x80); // MCS refclk Scale Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0047, 0x80);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_SYNC, 1); // Input a rising-edge pulse to the SYNC_IN pin
mdelay(500);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_SYNC, 0);
mdelay(2000);
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x0B); // MCS RF Enable; MCS Digital CLK Enable ; MCS BB Enable
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x0B);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_SYNC, 1); // Input another rising-edge pulse to the SYNC_IN pin
mdelay(500);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_SYNC, 0);
ad9361_reg_write(ad9361_1_reg_inst, 0x0001, 0x08); // clear MCS bits
ad9361_reg_write(ad9361_2_reg_inst, 0x0001, 0x08);
XGpio_WritePin(&Gpio, GPIO_BANK_OUT, AD9361_RX_FIFO_RST, 0);
return SUCCESS;
}// Hardware_Initialize
/*****************************************************************************/
/**
* @brief Initialize ScuTimer instance.
*
* @param InstPtr A pointer to QSPI instance
*
* @param DevId ScuTimer instance device ID
*
* @return SUCCESS
* XST_FAILURE
*
******************************************************************************/
int32_t ScuTimerInit(XTmrCtr* instPtr, uint16_t devId) {
int Status = SUCCESS;
XTmrCtr_Config *configPtr;
/*
* Initialize the Scu Private Timer driver.
*/
configPtr = XTmrCtr_LookupConfig(devId);
/*
* This is where the virtual address would be used, this example
* uses physical address.
*/
Status = XTmrCtr_Initialize(instPtr, configPtr->DeviceId);
if (Status != SUCCESS) {
return Status;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XTmrCtr_SelfTest(instPtr, XTC_TIMER_0);
return Status;
}// ScuTimerInit
/*****************************************************************************/
/**
* @brief Initialize XADC instance.
*
* @param InstPtr A pointer to QSPI instance
*
* @param DevId ScuTimer instance device ID
*
* @return SUCCESS
* XST_FAILURE
*
******************************************************************************/
int32_t XADC_Init(XSysMon* instPtr, uint16_t devId) {
int Status = SUCCESS;
XSysMon_Config *configPtr;
/*
* Initialize the Scu Private Timer driver.
*/
configPtr = XSysMon_LookupConfig(devId);
if (configPtr == NULL) {
return XST_FAILURE;
}
XSysMon_CfgInitialize(instPtr, configPtr, configPtr->BaseAddress);
//safe mode
XSysMon_SetSequencerMode(instPtr, XSM_SEQ_MODE_SAFE);
//enable channels
XSysMon_SetSeqChEnables(instPtr, XSM_SEQ_CH_TEMP|XSM_SEQ_CH_VCCINT);
/* Set the ADCCLK frequency equal to 1/32 of System clock for the System
* Monitor/ADC in the Configuration Register 2.
*/
XSysMon_SetAdcClkDivisor(instPtr, 32);
//mode
XSysMon_SetSequencerMode(instPtr, XSM_SEQ_MODE_CONTINPASS);
/*
* Wait till the End of Sequence occurs
*/
XSysMon_GetStatus(instPtr); /* Clear the old status */
while ((XSysMon_GetStatus(instPtr) & XSM_SR_EOS_MASK) !=
XSM_SR_EOS_MASK);
return Status;
}// XADC_Init
/****************************************************************************/
/**
* This function is responsible for initializing the SCUGIC instance, looking
* for the device configuration based on the unique device ID, initializing a
* SCUGIC instance, and initialize the interrupt at IRQ_F2P[0:0]
*
* @param deviceID is the XPAR_<GPIO_instance>_DEVICE_ID value from
* "xparameters.h".
* @param XIntc is a reference to the XScuGic driver Instance.
*
* @return SUCCESS if initialize successful.
* XST_FAILURE if initialization failed.
*
*****************************************************************************/
int32_t SetupInterruptSystem(XIntc* instPtr, uint32_t devId){
int Status = SUCCESS;
// Initialize the GIC instance.
Status = XIntc_Initialize(instPtr, devId);
if (Status != SUCCESS) {
return Status;
}
// Perform a self-test to ensure that the hardware was built correctly.
Status = XIntc_SelfTest(instPtr);
if (Status != SUCCESS) {
return Status;
}
/* Hook up interrupt service routine */
Status = XIntc_Connect(instPtr, PHY_INTR_ID,
(XInterruptHandler) PhyIntr_Handler, (void *) instPtr);
if (Status != SUCCESS) {
return Status;
}
/* Enable the interrupt vector at the interrupt controller */
XIntc_Enable(instPtr, PHY_INTR_ID);
/* Hook up interrupt service routine */
Status = XIntc_Connect(instPtr, C2C_TX_INTR_ID,
(XInterruptHandler) C2c_TxIntrHandler, (void *) instPtr);
if (Status != SUCCESS) {
return Status;
}
Status = XIntc_Connect(instPtr, C2C_RX_INTR_ID,
(XInterruptHandler) C2c_RxIntrHandler, (void *) instPtr);
if (Status != SUCCESS) {
return Status;
}
/* Enable the interrupt vector at the interrupt controller */
XIntc_Enable(instPtr, C2C_TX_INTR_ID);
XIntc_Enable(instPtr, C2C_RX_INTR_ID);
#ifdef GLINK_REMOTE_TEST_ENABLE
// ScuTimer interrupt
Status = XIntc_Connect(instPtr, SCUTIMER_INTR_ID,
(Xil_ExceptionHandler) Timer_IntrHandler,
(void *) &axiTimeInst);
if (Status != SUCCESS) {
return Status;
}
XIntc_Enable(instPtr, SCUTIMER_INTR_ID);
#endif
/* Start the interrupt controller such that interrupts are recognized
* and handled by the processor
*/
Status = XIntc_Start(instPtr, XIN_REAL_MODE);
if (Status != SUCCESS) {
return Status;
}
/* Initialize the exception table and register the interrupt controller
* handler with the exception table
*/
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XIntc_InterruptHandler,
(void *) instPtr);
// Enable non-critical exceptions
Xil_ExceptionEnable();
return SUCCESS;
} // SetupInterruptSystem
/****************************************************************************/
/**
* This is a utility function to implement a C2C data transmission.
*
* @param buffPtr a pointer to data buffer, which need to be 2 byte aligned.
* @param dataLen length of data needs to be sent.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
int32_t Intercom_C2cRecvData(void* buffPtr, int32_t buffSize){
int Status;
uint8_t* c2cRecvDataPtr;
if(isCircQueueEmpty(c2cRecvQueue)){
return EIGNORE;
}
else{
Status = CircQueuePop(c2cRecvQueue, (void**)(&c2cRecvDataPtr));
if(Status == false || c2cRecvDataPtr == NULL){
return FAILURE;
}
}
uint32_t recvLen = IO_In32((uintptr_t)(c2cRecvDataPtr + C2C_DLEN_OFFSET)) - C2C_HEADER_LEN;
memcpy(buffPtr, c2cRecvDataPtr + C2C_PLOAD_OFFSET, recvLen);
// Check if buffer is big enough.
if(buffSize < recvLen - C2C_EXTRA_LEN){
DBG_ERROR("Buffer too small.\r\n",);
return FAILURE;
}
// Check CRC
if(CrcCheck(buffPtr + recvLen - C2C_EXTRA_LEN, C2C_EXTRA_LEN) == true){
// Store received data
memcpy(c2cExtraBuffPtr, buffPtr + recvLen - C2C_EXTRA_LEN, sizeof(C2C_EXTRA));
}
else{
DBG_ERROR("C2C extra crc check failed.\r\n");
return ECRC;
}
return SUCCESS;
} //Intercom_C2cRecvData
/****************************************************************************/
/**
* This is a utility function to implement a C2C data transmission.
*
* @param buffPtr a pointer to data buffer, which need to be 2 byte aligned.
* @param dataLen length of data needs to be sent.
* @param subaddrId taget subAddress
*
* @return None.
*
* @note None.
*
*****************************************************************************/
int32_t Intercom_C2cSendData2Addr(void* buffPtr, int32_t dataLen, uint16_t subaddrId){
int Status;
if(dataLen > (C2C_BUFF_MAX - (sizeof(C2C_EXTRA)+COMMON_CRC_LEN))){
return FAILURE;
}
c2cExtraBuffPtr->glinkSubAddr = subaddrId;
memcpy((uint8_t *)(C2C_TXBUFF_ADDR_BASE + C2C_PLOAD_OFFSET), buffPtr, dataLen);
memcpy((uint8_t *)(C2C_TXBUFF_ADDR_BASE + C2C_PLOAD_OFFSET + dataLen), c2cExtraBuffPtr, sizeof(C2C_EXTRA));
Status = AppendCrc((uint8_t *)(C2C_TXBUFF_ADDR_BASE + C2C_PLOAD_OFFSET + dataLen), C2C_EXTRA_LEN);
if(Status != SUCCESS){
DBG_ERROR("C2C extra data crc append error, with error code: %d.\r\n", Status);
return Status;
}
Status = C2c_BlockingSendData(c2cInstPtr, (uint8_t *)C2C_TXBUFF_ADDR_BASE, dataLen + C2C_EXTRA_LEN);
// FIXME
usleep(1);
return Status;
}// Intercom_C2cSendData2Addr
/****************************************************************************/
/**
* 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!
*
* @param callBackRef is the SCUGIC instance pointer.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
uint32_t c2cRecvCnt = 0;
void C2c_RxIntrHandler(void *callBackRef) {
int32_t Status;
Status = C2c_RecvIrqHandler(c2cInstPtr);
if(Status != SUCCESS){
_nop_();
}
CircQueuePush(c2cRecvQueue, (void *)c2cInstPtr->lastRxBuff);
uint8_t* nextRxBuff = (c2cInstPtr->lastRxBuff >= C2C_RXBUFF_ADDR_BASE + (C2C_BUFF_NUM-1)*C2C_BUFF_SIZE) ?
(uint8_t*)C2C_RXBUFF_ADDR_BASE : (uint8_t*)(c2cInstPtr->lastRxBuff + C2C_BUFF_SIZE);
C2c_RecvData(c2cInstPtr, nextRxBuff, C2C_BUFF_SIZE);
c2cRecvCnt ++;
return;
} // C2cRxIntr_Handler
/****************************************************************************/
/**
* 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!
*
* @param callBackRef is the SCUGIC instance pointer.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
uint32_t c2cSendvCnt = 0;
void C2c_TxIntrHandler(void *callBackRef) {
int32_t Status;
Status = C2c_SendIrqHandler(c2cInstPtr);
if(Status != SUCCESS){
_nop_();
}
c2cSendvCnt ++;
return;
} // C2cTxIntr_Handler
/****************************************************************************/
/**
* 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!
*
* @param callBackRef is the SCUGIC instance pointer.
*
* @return None.
*
* @note None.
*
*****************************************************************************/
uint32_t phyIntrCnt = 0;
void PhyIntr_Handler(void *callBackRef) {
phyIntrCnt++;
Phy_UpdateState(phyInstPtr);
// Check last frame.
if (Phy_IsFrameValid(phyInstPtr) == true) {
Phy_RetrieveRecvData(phyInstPtr, intrCommInstPtr->phyRecvBuff);
isPhyUploadAsserted = true;
}
return;
} // PhyIntr_Handler
/*****************************************************************************/
/**
* @brief Handler of ScuTimer interrupt.
*
* @param CallBackRef A pointer to corresponding ScuTimer instance.
*
* @return None.
*
******************************************************************************/
#ifdef GLINK_REMOTE_TEST_ENABLE
void Timer_IntrHandler(void* CallBackRef) {
ASSERT(CallBackRef != NULL);
XTmrCtr *TimerInstPtr = (XTmrCtr *) CallBackRef;
XTmrCtr_InterruptHandler(TimerInstPtr);
isSendRemotCheckAsserted = true;
return;
} //Timer_IntrHandler
#endif
/*****************************************************************************/
/**
* @brief Main function, initialize all the device needed, initialize
* interrupt system, halt in while(1) wait for event interrupt.
*
* @param None.
*
* @return
*
******************************************************************************/
int main(void) {
int Status;
/*** Initialize Hardware AD9361 AD9516 ***/
Status = Hardware_Initialize();
if (Status == SUCCESS) {
DBG_PRINT("Hardware Init SUCCESS! \r\n");
}
else {
DBG_PRINT("Hardware Init FAILED! \r\n");
return Status;
}
#ifdef GLINK_REMOTE_TEST_ENABLE
/*** Initialize Remote Test Updater Module ***/
//-- ScuTimer Initialization
Status = ScuTimerInit(&axiTimeInst, SCUTIMER_DEVICE_ID);
if (Status == SUCCESS) {
DBG_INFO("ScuTimer Init SUCCESS! \r\n");
}
else {
DBG_ERROR("ScuTimer Init FAILED, ErrorCode: 0x%08X\r\n, Status");
return Status;
}
XTmrCtr_InitHw(&axiTimeInst);
//-- XADC Initialization
Status = XADC_Init(&SysMonInst, SYSMON_DEVICE_ID);
if (Status == SUCCESS) {
DBG_INFO("XADC Init SUCCESS! \r\n");
}
else {
DBG_ERROR("XADC Init FAILED, ErrorCode: 0x%08X\r\n, Status");
return Status;
}
#endif
/*** Initialize C2C bridge ***/
//-- Buffer Initialization
Status = CircQueueCreate(&c2cRecvQueue, C2C_BUFF_NUM);
if (Status == true) {
DBG_PRINT("CircQueue Creat SUCCESS! \r\n");
}
else {
DBG_PRINT("CircQueue Creat FAILED! \r\n");
return EUNEXP;
}
c2cExtraBuffPtr = (C2C_EXTRA*) malloc(sizeof(C2C_EXTRA));
if ((c2cExtraBuffPtr) == NULL) {
DBG_PRINT("c2cExtraBuffPtr allocate FAILED! \r\n");
return EALLOC;
}
//-- C2C Hardware Initialization
Status = C2c_Init(&c2cInstPtr, &c2cConfig);
if (Status == SUCCESS) {
DBG_INFO("C2C bridge Init SUCCESS! \r\n");
}
else {
DBG_ERROR("C2C bridge Init FAILED, ErrorCode: %d\r\n, Status");
return Status;
}
//-- C2C Intercommunication Module Initialization
intrCommConfig.phyInstPtr = phyInstPtr;
Status = InterComm_Init(&intrCommInstPtr, &intrCommConfig);
if (Status == SUCCESS) {
DBG_INFO("nterComm Init SUCCESS! \r\n");
}
else {
DBG_ERROR("nterComm Init FAILED, ErrorCode: %d\r\n, Status");
return Status;
}
//-- Start C2C Receiving Process
Status = C2c_RecvData(c2cInstPtr, (uint8_t*)C2C_RXBUFF_ADDR_BASE, C2C_BUFF_SIZE);
if (Status == SUCCESS) {
DBG_PRINT("C2C start listening SUCCESS! \r\n");
}
else {
DBG_PRINT("C2C start listening FAILED! \r\n");
return Status;
}
//-- Enable C2C Interrupts
Status = C2c_IrqEnable(c2cInstPtr);
if (Status == SUCCESS) {
DBG_INFO("Glink interrupts enable SUCCESS!\r\n");
}
else {
DBG_ERROR("Glink interrupts enable FAILED, with error code: %d.\r\n", Status);
return Status;
}
/*** Initialize Physical Layer Control Module ***/
//-- Physical Layer Hardware Initialization
Status = Phy_InstInit(&phyInstPtr, &phyConfig);
if (Status == SUCCESS) {
DBG_PRINT("PhyCtrl Init SUCCESS! \r\n");
}
else {
DBG_PRINT("PhyCtrl Init FAILED! \r\n");
return Status;
}
//-- Set Physical Layer Mode
Status = Phy_SetMode(phyInstPtr, PHY_MODE_PULL);
if (Status == SUCCESS) {
DBG_PRINT("Physical Mode %u Setup SUCCESS! \r\n", PHY_MODE_LISTEN);
}
else {
DBG_PRINT("Physical Mode %u Setup FAILED! \r\n", PHY_MODE_LISTEN);
return Status;
}
/*** Initialize GIC ***/
Status = SetupInterruptSystem(&intcInst, INTC_DEVICE_ID);
if (Status == SUCCESS) {
DBG_INFO("Intc Init SUCCESS! \r\n");
}
else {
DBG_ERROR("Intc Init FAILED, ErrorCode: %d\r\n, Status");
return Status;
}
#ifdef GLINK_REMOTE_TEST_ENABLE
// Start Remote Control Timer
XTmrCtr_SetLoadReg(axiTimeInst.BaseAddress, XTC_TIMER_0, TIMER_COUNT_MAX);
XTmrCtr_SetControlStatusReg(axiTimeInst.BaseAddress, XTC_TIMER_0,
XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK |
XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK);
XTmrCtr_Start(&axiTimeInst,XTC_TIMER_0);
XTmrCtr_Start(&axiTimeInst,XTC_TIMER_0);
#endif
DBG_PRINT("Starting Physical Layer...");
Phy_Start(phyInstPtr);
/*** Main Routine - Handling C2C Handshake ***/
while(true){
// Upload physical frame data if new frame received.
if(isPhyUploadAsserted && !C2c_IsSendBusy(c2cInstPtr)){
isPhyUploadAsserted = false;
Status = InterComm_PhyDataUpload(intrCommInstPtr);
if(Status != SUCCESS){
DBG_PRINT("####\tInterComm L1 data upload finished with code: %d", Status);
continue;
}
}
// Handle received intercom frame if received.
else if(isCircQueueEmpty(c2cRecvQueue) == false){
Status = InterComm_RecvMsg(intrCommInstPtr);
if(Status != SUCCESS){
DBG_PRINT("####\tInterComm L1 data upload finished with code: %d.\r\n", Status);
continue;
}
else{
Status = InterComm_MsgHandler(intrCommInstPtr);
if(Status != SUCCESS){
DBG_PRINT("####\tInterComm message handler finished with code: %d\n\r", Status);
continue;
}
}
}
#ifdef GLINK_REMOTE_TEST_ENABLE
// Update remote monitoring info if needed.
else if(isSendRemotCheckAsserted && !C2c_IsSendBusy(c2cInstPtr)){
isSendRemotCheckAsserted = false;
Status = InterComm_SendRemotCheck(intrCommInstPtr, &SysMonInst, c2cExtraBuffPtr);
if(Status != SUCCESS){
DBG_PRINT("####\tInterComm L1 data upload finished with code: %d", Status);
}
}
#endif
}// Waiting for interrupt
// uint8_t * sendBuffPtr = (uint8_t *)C2C_TXBUFF_ADDR_BASE;
// uint32_t cnt = 0;
// while(cnt < 10240){
// if(!C2c_IsSendBusy(c2cInstPtr)){
// for(int i = 0; i < 512; i++){
// sendBuffPtr[i] = i + cnt;
// }
// C2c_BlockingSendData(c2cInstPtr, sendBuffPtr, 512);
// cnt++;
// }
// }
// while(true);
} // main