add MPC module to GE project
This commit is contained in:
@@ -71,9 +71,10 @@
|
|||||||
#define TIME_CONTROLLER_BASEADDR XPAR_TMC_BASEADDR
|
#define TIME_CONTROLLER_BASEADDR XPAR_TMC_BASEADDR
|
||||||
|
|
||||||
// System Bus Configs
|
// System Bus Configs
|
||||||
//#define SYSBUS_BASE_ADDR XPAR_SYSTEMBUS_BASEADDR
|
#define MPC_BRAM_ID XPAR_MPC_BRAM_INTERFACE_MPC_BRAM_CTRL_DEVICE_ID
|
||||||
//#define SYSBUS_TX_INTR_ID XPAR_FABRIC_SYSTEMBUS_TX_DONE_INTR
|
#define MPC_GPIO_ID XPAR_MPC_GPIO_DEVICE_ID
|
||||||
//#define SYSBUS_RX_INTR_ID XPAR_FABRIC_SYSTEMBUS_RX_DONE_INTR
|
#define MPC_TX_INTR_ID XPAR_FABRIC_MPC_TX_IRQ_INTR
|
||||||
|
#define MPC_RX_INTR_ID XPAR_FABRIC_MPC_RX_IRQ_INTR
|
||||||
|
|
||||||
// Global Timer config
|
// Global Timer config
|
||||||
#define GLOBAL_TIMER_DEVICE_ID XPAR_GLOBAL_TMR_DEVICE_ID
|
#define GLOBAL_TIMER_DEVICE_ID XPAR_GLOBAL_TMR_DEVICE_ID
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ struct xil_timer_init_param xil_scutimer_init_param = {
|
|||||||
struct timer_init_param scutimer_init_param = {
|
struct timer_init_param scutimer_init_param = {
|
||||||
.id = SCUTIMER_DEVICE_ID,
|
.id = SCUTIMER_DEVICE_ID,
|
||||||
.freq_hz = SCU_TIMER_CLK_HZ,
|
.freq_hz = SCU_TIMER_CLK_HZ,
|
||||||
.ticks_count = (SCU_TIMER_CLK_HZ/10), //update log every 100ms
|
.ticks_count = (SCU_TIMER_CLK_HZ/2), //update log every 500ms
|
||||||
.platform_ops = &xil_timer_ops,
|
.platform_ops = &xil_timer_ops,
|
||||||
.extra = &xil_scutimer_init_param
|
.extra = &xil_scutimer_init_param
|
||||||
};
|
};
|
||||||
|
|||||||
+110
-106
@@ -36,7 +36,7 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "config/app_config.h"
|
#include "config/app_config.h"
|
||||||
#include "dev_profile/dev_profile.h"
|
#include "dev_profile/dev_profile.h"
|
||||||
#include "systembus/systembus.h"
|
#include "mpc/mpc.h"
|
||||||
#include "networking/phy_layer/phy_layer.h"
|
#include "networking/phy_layer/phy_layer.h"
|
||||||
#include "networking/link_layer/link_layer.h"
|
#include "networking/link_layer/link_layer.h"
|
||||||
// RF-Driver
|
// RF-Driver
|
||||||
@@ -48,8 +48,8 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr);
|
|||||||
void Phy_IntrHandler(void *context);
|
void Phy_IntrHandler(void *context);
|
||||||
void PeriodicPull_Handler(void *callBackRef);
|
void PeriodicPull_Handler(void *callBackRef);
|
||||||
void ScuTimer_IntrHandler(void *context);
|
void ScuTimer_IntrHandler(void *context);
|
||||||
void Systembus_RxIntrHandler(void *context);
|
void Mpc_RxIntrHandler(void *context);
|
||||||
void Systembus_TxIntrHandler(void *context);
|
void Mpc_TxIntrHandler(void *context);
|
||||||
/************************** Constant Definitions *****************************/
|
/************************** Constant Definitions *****************************/
|
||||||
struct callback_desc phy_callback_desc =
|
struct callback_desc phy_callback_desc =
|
||||||
{
|
{
|
||||||
@@ -64,15 +64,15 @@ struct callback_desc periodicpull_callback_desc =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct callback_desc sysbus_rx_callback_desc =
|
struct callback_desc mpc_rx_callback_desc =
|
||||||
{
|
{
|
||||||
.callback = Systembus_RxIntrHandler,
|
.callback = Mpc_RxIntrHandler,
|
||||||
.ctx = NULL
|
.ctx = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct callback_desc sysbus_tx_callback_desc =
|
struct callback_desc mpc_tx_callback_desc =
|
||||||
{
|
{
|
||||||
.callback = Systembus_TxIntrHandler,
|
.callback = Mpc_TxIntrHandler,
|
||||||
.ctx = NULL
|
.ctx = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,15 +126,16 @@ TMC_CONFIG tmcConfig =
|
|||||||
.reset = 10
|
.reset = 10
|
||||||
};
|
};
|
||||||
|
|
||||||
//static SYSBUS_CONFIG sysbusConfig = {
|
static MPC_CONFIG mpcConfig = {
|
||||||
// .baseAddr = SYSBUS_BASE_ADDR,
|
.bramId = MPC_BRAM_ID,
|
||||||
// .txQueueMax = 16,
|
.gpioId = MPC_GPIO_ID,
|
||||||
// .rxQueueMax = 16
|
.txQueueMax = 16,
|
||||||
//};
|
.rxQueueMax = 16
|
||||||
|
};
|
||||||
/************************** Function Prototypes ******************************/
|
/************************** Function Prototypes ******************************/
|
||||||
static struct irq_ctrl_desc *intcDescPtr; // General interrupt controller descriptor
|
static struct irq_ctrl_desc *intcDescPtr; // General interrupt controller descriptor
|
||||||
static struct timer_desc *logTmPtr;
|
static struct timer_desc *logTmPtr;
|
||||||
static SYSBUS *sysbusDescPtr;
|
static MPC *mpcDescPtr;
|
||||||
static PHY_INST *phyInstPtr;
|
static PHY_INST *phyInstPtr;
|
||||||
static TMC_INST *tmcInstPtr = NULL;
|
static TMC_INST *tmcInstPtr = NULL;
|
||||||
L2_INST *linkInstPtr;
|
L2_INST *linkInstPtr;
|
||||||
@@ -213,64 +214,64 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /* Initialize system bus interrupt. */
|
/* Initialize system bus interrupt. */
|
||||||
// Status = irq_trigger_level_set(descPtr, SYSBUS_TX_INTR_ID, IRQ_EDGE_RISING);
|
Status = irq_trigger_level_set(descPtr, MPC_TX_INTR_ID, IRQ_EDGE_RISING);
|
||||||
// if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
// {
|
{
|
||||||
// DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
||||||
// return Status;
|
return Status;
|
||||||
// }
|
}
|
||||||
// // Set interrupt priority
|
// Set interrupt priority
|
||||||
// Status = irq_set_priority(descPtr, SYSBUS_TX_INTR_ID, 0x10);
|
Status = irq_set_priority(descPtr, MPC_TX_INTR_ID, 0x10);
|
||||||
// if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
// {
|
{
|
||||||
// DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
||||||
// return Status;
|
return Status;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// // Connect the interrupt service routine isr1 to the interrupt controller
|
// Connect the interrupt service routine isr1 to the interrupt controller
|
||||||
// Status = irq_register_callback(descPtr, SYSBUS_TX_INTR_ID, &sysbus_tx_callback_desc);
|
Status = irq_register_callback(descPtr, MPC_TX_INTR_ID, &mpc_tx_callback_desc);
|
||||||
// if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
// {
|
{
|
||||||
// DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
||||||
// return Status;
|
return Status;
|
||||||
// }
|
}
|
||||||
// Status = irq_trigger_level_set(descPtr, SYSBUS_RX_INTR_ID, IRQ_EDGE_RISING);
|
Status = irq_trigger_level_set(descPtr, MPC_RX_INTR_ID, IRQ_EDGE_RISING);
|
||||||
// if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
// {
|
{
|
||||||
// DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
||||||
// return Status;
|
return Status;
|
||||||
// }
|
}
|
||||||
// // Set interrupt priority
|
// Set interrupt priority
|
||||||
// Status = irq_set_priority(descPtr, SYSBUS_RX_INTR_ID, 0x18);
|
Status = irq_set_priority(descPtr, MPC_RX_INTR_ID, 0x18);
|
||||||
// if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
// {
|
{
|
||||||
// DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
||||||
// return Status;
|
return Status;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// // Connect the interrupt service routine isr1 to the interrupt controller
|
// Connect the interrupt service routine isr1 to the interrupt controller
|
||||||
// Status = irq_register_callback(descPtr, SYSBUS_RX_INTR_ID, &sysbus_rx_callback_desc);
|
Status = irq_register_callback(descPtr, MPC_RX_INTR_ID, &mpc_rx_callback_desc);
|
||||||
// if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
// {
|
{
|
||||||
// DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
||||||
// return Status;
|
return Status;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// /* Initialize Scu timer interrupt. */
|
/* Initialize Scu timer interrupt. */
|
||||||
// // Connect the interrupt service routine isr1 to the interrupt controller
|
// Connect the interrupt service routine isr1 to the interrupt controller
|
||||||
// Status = irq_register_callback(descPtr, SCUTIMER_INTR_ID, &scutm_callback_desc);
|
Status = irq_register_callback(descPtr, SCUTIMER_INTR_ID, &scutm_callback_desc);
|
||||||
// if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
// {
|
{
|
||||||
// DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
DBG_ERROR("PHY_INTR register callback FAILED, ErrorCode: %" PRId32 ".\n", Status);
|
||||||
// return Status;
|
return Status;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// Enable interrupts
|
// Enable interrupts
|
||||||
irq_enable(descPtr, PHY_INTR_ID);
|
irq_enable(descPtr, PHY_INTR_ID);
|
||||||
irq_enable(descPtr, PERIODIC_5MS_INTR_ID);
|
irq_enable(descPtr, PERIODIC_5MS_INTR_ID);
|
||||||
// irq_enable(descPtr, SYSBUS_RX_INTR_ID);
|
irq_enable(descPtr, MPC_RX_INTR_ID);
|
||||||
// irq_enable(descPtr, SYSBUS_TX_INTR_ID);
|
irq_enable(descPtr, MPC_TX_INTR_ID);
|
||||||
irq_enable(descPtr, SCUTIMER_INTR_ID);
|
irq_enable(descPtr, SCUTIMER_INTR_ID);
|
||||||
|
|
||||||
// Enable Exceptions
|
// Enable Exceptions
|
||||||
@@ -328,13 +329,13 @@ void PeriodicPull_Handler(void *callBackRef)
|
|||||||
* @return None.
|
* @return None.
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void Systembus_RxIntrHandler(void *context)
|
void Mpc_RxIntrHandler(void *context)
|
||||||
{
|
{
|
||||||
int32_t Status;
|
int32_t Status;
|
||||||
Status = SystemBus_RxIntrHandler(sysbusDescPtr);
|
Status = Mpc_RxIrqHandler(mpcDescPtr);
|
||||||
if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
{
|
{
|
||||||
DBG_ERROR("SystemBus_RxIntrHandler exit with error code %" PRId32 ",\n", Status);
|
DBG_ERROR("Mpc_RxIrqHandler exit with error code %" PRId32 ",\n", Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,13 +348,13 @@ void Systembus_RxIntrHandler(void *context)
|
|||||||
* @return None.
|
* @return None.
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void Systembus_TxIntrHandler(void *context)
|
void Mpc_TxIntrHandler(void *context)
|
||||||
{
|
{
|
||||||
int32_t Status;
|
int32_t Status;
|
||||||
Status = SystemBus_TxIntrHandler(sysbusDescPtr);
|
Status = Mpc_TxIrqHandler(mpcDescPtr);
|
||||||
if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
{
|
{
|
||||||
DBG_ERROR("SystemBus_TxIntrHandler exit with error code %" PRId32 ",\n", Status);
|
DBG_ERROR("Mpc_TxIrqHandler exit with error code %" PRId32 ",\n", Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,6 +375,15 @@ void ScuTimer_IntrHandler(void *context)
|
|||||||
{
|
{
|
||||||
// Refresh log
|
// Refresh log
|
||||||
Phy_RefreshHwSate(phyInstPtr);
|
Phy_RefreshHwSate(phyInstPtr);
|
||||||
|
|
||||||
|
if (Mpc_IsEnable(mpcDescPtr))
|
||||||
|
{
|
||||||
|
if (Mpc_PendRemoteTest(mpcDescPtr) != SUCCESS)
|
||||||
|
{
|
||||||
|
DBG_ERROR("Failed to apply remote test.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
|
XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -458,13 +468,13 @@ int main(void)
|
|||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /* System Bus Initialize */
|
/* System Bus Initialize */
|
||||||
// Status = SystemBus_Init(&sysbusDescPtr, &sysbusConfig);
|
Status = Mpc_Init(&mpcDescPtr, &mpcConfig);
|
||||||
// if (Status != SUCCESS)
|
if (Status != SUCCESS)
|
||||||
// {
|
{
|
||||||
// DBG_ERROR("Systembus init FAILED, with error code: %" PRId32 "\n", Status);
|
DBG_ERROR("MPC init FAILED, with error code: %" PRId32 "\n", Status);
|
||||||
// return Status;
|
return Status;
|
||||||
// }
|
}
|
||||||
|
|
||||||
/* System Monitor log timer Initialize */
|
/* System Monitor log timer Initialize */
|
||||||
Status = timer_init(&logTmPtr, &scutimer_init_param);
|
Status = timer_init(&logTmPtr, &scutimer_init_param);
|
||||||
@@ -492,30 +502,24 @@ int main(void)
|
|||||||
DBG_PRINT("Physical started...\n");
|
DBG_PRINT("Physical started...\n");
|
||||||
Phy_Start(phyInstPtr);
|
Phy_Start(phyInstPtr);
|
||||||
|
|
||||||
Linklayer_Start(linkInstPtr);
|
while (true)
|
||||||
|
{
|
||||||
while (true);
|
// System bus handler
|
||||||
|
if (Mpc_IsReqPending(mpcDescPtr))
|
||||||
// while (true)
|
{
|
||||||
// {
|
Status = Mpc_HandleCmd(mpcDescPtr);
|
||||||
// // System bus handler
|
if (Status != SUCCESS)
|
||||||
// if (SystemBus_IsReqPendding(sysbusDescPtr))
|
{
|
||||||
// {
|
DBG_ERROR("Mpc_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
|
||||||
// Status = SystemBus_HandleCmd(sysbusDescPtr);
|
}
|
||||||
// if (Status != SUCCESS)
|
}
|
||||||
// {
|
if (Mpc_IsRsqPending(mpcDescPtr) && (!Mpc_IsTxBusy(mpcDescPtr)))
|
||||||
// DBG_ERROR("SystemBus_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
|
{
|
||||||
// }
|
Status = Mpc_MakeResp(mpcDescPtr);
|
||||||
// }
|
if (Status != SUCCESS)
|
||||||
// if (SystemBus_IsRsqPendding(sysbusDescPtr) && (!SystemBus_IsTxBusy(sysbusDescPtr)))
|
{
|
||||||
// {
|
DBG_ERROR("Mpc_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
|
||||||
// // FIXME: Required by 12 (CASC)
|
}
|
||||||
// udelay(200);
|
}
|
||||||
// Status = SystemBus_MakeResp(sysbusDescPtr);
|
}
|
||||||
// if (Status != SUCCESS)
|
|
||||||
// {
|
|
||||||
// DBG_ERROR("SystemBus_HandleCmd exit with ErrorCode: %" PRId32 ".\n", Status);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
} // main
|
} // main
|
||||||
|
|||||||
@@ -0,0 +1,601 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* Description: MPC protocol implementation file.
|
||||||
|
*
|
||||||
|
* Date: 2023-05-06 10:13
|
||||||
|
* Last Edit Time: [2023-05-06 21:45]
|
||||||
|
*
|
||||||
|
* Revisions: Rev 0.0
|
||||||
|
* History:
|
||||||
|
* [2023-05-06]: Initial version.
|
||||||
|
* [2023-09-13]: Update to 485 protocol-20220816
|
||||||
|
*
|
||||||
|
* Copyright(c) 2021 Beijing Institute of Technology.
|
||||||
|
* Lab of Communication and Network
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/***************************** Include Files *********************************/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "mpc.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "error.h"
|
||||||
|
#include "circ_queue.h"
|
||||||
|
#include "xbram.h"
|
||||||
|
#include "xgpio.h"
|
||||||
|
|
||||||
|
#include "../system_monitor.h"
|
||||||
|
|
||||||
|
/************************** Constant Definitions *****************************/
|
||||||
|
// Common Field
|
||||||
|
// -- Command word
|
||||||
|
#define WD_CMD 0x00
|
||||||
|
|
||||||
|
// -- Production type
|
||||||
|
#define WD_PRD 0x01
|
||||||
|
#define PRD_DL_K 0xDD
|
||||||
|
#define PRD_DL_S 0xEE
|
||||||
|
#define PRD_ALL 0xFF
|
||||||
|
|
||||||
|
// Self-Test
|
||||||
|
#define CMD_SELF_TEST 0xE1
|
||||||
|
// -- Request
|
||||||
|
// -- -- --
|
||||||
|
// -- Response
|
||||||
|
// -- -- Self-Test Result
|
||||||
|
#define ST_RSP_LEN 16
|
||||||
|
#define WD_ST_RET 0x02
|
||||||
|
#define ST_RET_OK 0xAA
|
||||||
|
#define ST_RET_ERROR 0x55
|
||||||
|
#define ST_RET_INFO_LEN 13
|
||||||
|
// -- -- Signal processor PS voltage
|
||||||
|
#define WD_SP_FPGA_VOLT 0x03
|
||||||
|
// -- -- Signal processor PS AUX voltage
|
||||||
|
#define WD_SP_CLK_STATE 0x04
|
||||||
|
// -- -- Signal processor DDR voltage
|
||||||
|
#define WD_SP_AD_LOCK_STATE 0x05
|
||||||
|
// -- -- Signal processor PL voltage
|
||||||
|
#define WD_SP_AD_TEMP_0 0x06
|
||||||
|
// -- -- Signal processor PL AUX voltage
|
||||||
|
#define WD_SP_AD_TEMP_1 0x07
|
||||||
|
// -- -- Signal processor Bram voltage
|
||||||
|
#define WD_SP_FPGA_TEMP 0x08
|
||||||
|
|
||||||
|
// -- -- Signal processor antenna voltage status
|
||||||
|
#define WD_ANT_VOLT 0x09
|
||||||
|
|
||||||
|
// -- -- Signal processor antenna RF temperature
|
||||||
|
#define WD_ANT_RF_TEMP 0x0A
|
||||||
|
// -- -- Signal processor antenna PLL lock status
|
||||||
|
#define WD_ANT_RF_PLL 0x0B
|
||||||
|
// -- -- Signal processor antenna MGC
|
||||||
|
#define WD_ANT_MGC_0 0x0C
|
||||||
|
#define WD_ANT_MGC_1 0x0D
|
||||||
|
// -- -- Reserved
|
||||||
|
#define WD_ANT_RESERVE 0x0E
|
||||||
|
|
||||||
|
// Data Send Test Command
|
||||||
|
#define CMD_DATA_TEST_A 0xE2
|
||||||
|
// -- Request
|
||||||
|
#define DATA_TEST_REQ_A_LEN 68
|
||||||
|
// -- -- 68 byte payload
|
||||||
|
// -- Response
|
||||||
|
#define DATA_TEST_RSP_A_LEN 68
|
||||||
|
// -- -- 68 byte payload
|
||||||
|
|
||||||
|
// Data Send Test Command
|
||||||
|
#define CMD_DATA_TEST_B 0xF2
|
||||||
|
// -- Request
|
||||||
|
#define DATA_TEST_REQ_B_LEN 170
|
||||||
|
// -- -- 170 byte payload
|
||||||
|
// -- Response
|
||||||
|
#define DATA_TEST_RSP_B_LEN 170
|
||||||
|
// -- -- 170 byte payload
|
||||||
|
|
||||||
|
// Config load
|
||||||
|
#define CMD_CONFIG 0xE3
|
||||||
|
// -- Request
|
||||||
|
#define WD_EN_CMD 0x02
|
||||||
|
#define EN_CMD_ON_HIGH_POWER 0x66
|
||||||
|
#define EN_CMD_ON_LOW_POWER 0x77
|
||||||
|
#define EN_CMD_SILENT 0x88
|
||||||
|
|
||||||
|
#define WD_MODE_CMD 0x03
|
||||||
|
#define MODE_CMD_HEAD 0x11
|
||||||
|
#define MODE_CMD_MEMBER 0x00
|
||||||
|
// -- Response
|
||||||
|
// -- -- none response
|
||||||
|
|
||||||
|
// System info update
|
||||||
|
#define CMD_SYS_INFO 0x33
|
||||||
|
#define SYS_INFO_OFFSET 2
|
||||||
|
// -- Request
|
||||||
|
// -- -- 54 byte system info
|
||||||
|
// -- Response
|
||||||
|
// -- -- none response
|
||||||
|
|
||||||
|
// Data Send Test Command
|
||||||
|
#define CMD_FLJ_SEND 0xE4
|
||||||
|
#define FLJ_DATA_OFFSET 2
|
||||||
|
// -- Request
|
||||||
|
// -- -- 78 byte payload
|
||||||
|
// -- Response
|
||||||
|
// -- -- none response
|
||||||
|
|
||||||
|
// Data Send Test Command
|
||||||
|
#define CMD_LJ_SEND 0xF4
|
||||||
|
#define LJ_DATA_OFFSET 2
|
||||||
|
// -- Request
|
||||||
|
// -- -- 156 byte payload
|
||||||
|
// -- Response
|
||||||
|
// -- -- none response
|
||||||
|
|
||||||
|
// FLJ Poll
|
||||||
|
#define CMD_FLJ_POLL 0xE5
|
||||||
|
// -- Request
|
||||||
|
#define WD_FLJ_POLL 0x02
|
||||||
|
#define FLJ_POLL_CODE 0x77
|
||||||
|
// -- Response
|
||||||
|
#define FLJ_POLL_RESP_LEN 170
|
||||||
|
// -- -- received 170 byte payload
|
||||||
|
|
||||||
|
// LJ Poll
|
||||||
|
#define CMD_LJ_POLL 0xF5
|
||||||
|
// -- Request
|
||||||
|
#define WD_LJ_POLL 0x02
|
||||||
|
#define LJ_POLL_CODE 0x77
|
||||||
|
// -- Response
|
||||||
|
#define LJ_POLL_RESP_LEN 68
|
||||||
|
// -- -- received 68 byte payload
|
||||||
|
|
||||||
|
// Remote Test
|
||||||
|
#define RM_TEST_RESP_LEN 158
|
||||||
|
#define WD_RM_TEST 0x02
|
||||||
|
#define RM_TEST_CODE 0x99
|
||||||
|
// -- Response
|
||||||
|
#define WD_TIME_STAMP 0x02
|
||||||
|
#define WD_TIME_STAMP_LEN 8
|
||||||
|
#define WD_SYSBUS_LOG 0x0A
|
||||||
|
#define WD_SYSBUS_LOG_LEN 14
|
||||||
|
#define WD_LINK_LOG 0x18
|
||||||
|
#define WD_LINK_LOG_LEN 64
|
||||||
|
#define WD_PHY_LOG 0x58
|
||||||
|
#define WD_PHY_LOG_LEN 57
|
||||||
|
#define WD_HARDWARE_ST 0x91
|
||||||
|
#define WD_HARDWARE_ST_LEN 13
|
||||||
|
|
||||||
|
// Remote Test FLJ
|
||||||
|
#define CMD_FLJ_RM_TEST 0xE6
|
||||||
|
// -- Request
|
||||||
|
#define WD_FLJ_RM_TEST 0x02
|
||||||
|
#define FLJ_RM_TEST_CODE 0x99
|
||||||
|
// -- Response
|
||||||
|
#define WD_FLJ_TIME_STAMP 0x02
|
||||||
|
#define WD_FLJ_TIME_STAMP_LEN 8
|
||||||
|
#define WD_FLJ_SYSBUS_LOG 0x0A
|
||||||
|
#define WD_FLJ_SYSBUS_LOG_LEN 14
|
||||||
|
#define WD_FLJ_LINK_LOG 0x18
|
||||||
|
#define WD_FLJ_LINK_LOG_LEN 64
|
||||||
|
#define WD_FLJ_PHY_LOG 0x58
|
||||||
|
#define WD_FLJ_PHY_LOG_LEN 57
|
||||||
|
#define WD_FLJ_HARDWARE_ST 0x91
|
||||||
|
#define WD_FLJ_HARDWARE_ST_LEN 13
|
||||||
|
|
||||||
|
// Remote Test LJ
|
||||||
|
#define CMD_LJ_RM_TEST 0xF6
|
||||||
|
// -- Request
|
||||||
|
#define WD_LJ_RM_TEST 0x02
|
||||||
|
#define LJ_RM_TEST_CODE 0x99
|
||||||
|
// -- Response
|
||||||
|
#define WD_LJ_TIME_STAMP 0x02
|
||||||
|
#define WD_LJ_TIME_STAMP_LEN 8
|
||||||
|
#define WD_LJ_SYSBUS_LOG 0x0A
|
||||||
|
#define WD_LJ_SYSBUS_LOG_LEN 14
|
||||||
|
#define WD_LJ_LINK_LOG 0x18
|
||||||
|
#define WD_LJ_LINK_LOG_LEN 64
|
||||||
|
#define WD_LJ_PHY_LOG 0x58
|
||||||
|
#define WD_LJ_PHY_LOG_LEN 57
|
||||||
|
#define WD_LJ_HARDWARE_ST 0x91
|
||||||
|
#define WD_LJ_HARDWARE_ST_LEN 13
|
||||||
|
|
||||||
|
// My Production Type
|
||||||
|
#define MY_PRD_ID PRD_DL_K
|
||||||
|
|
||||||
|
/************************** Function Prototypes ******************************/
|
||||||
|
/**************************** Type Definitions *******************************/
|
||||||
|
/************************** Variable Definitions *****************************/
|
||||||
|
// TODO: better approach?
|
||||||
|
#include "../networking/link_layer/link_layer.h"
|
||||||
|
#include "../networking/phy_layer/phy_layer.h"
|
||||||
|
extern L2_INST *linkInstPtr;
|
||||||
|
extern L2_CONFIG linkConfig;
|
||||||
|
|
||||||
|
inline bool Mpc_IsEnable(MPC *instPtr)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
return (instPtr->isEnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Mpc_IsReqPending(MPC *instPtr)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
return (!isCircQueueEmpty(instPtr->rxQueue));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Mpc_IsRsqPending(MPC *instPtr)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
return (!isCircQueueEmpty(instPtr->txQueue));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Mpc_IsTxBusy(MPC *instPtr)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
return (!instPtr->isTxDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Mpc_IsRxBusy(MPC *instPtr)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
return (!instPtr->isRxDone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Apply system configuration
|
||||||
|
*/
|
||||||
|
static int32_t Mpc_SystemConfig(MPC *instPtr, uint8_t *msg)
|
||||||
|
{
|
||||||
|
PHY_INST *phyRef = linkInstPtr->config.phyInstPtr;
|
||||||
|
TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr;
|
||||||
|
bool reconfig = false;
|
||||||
|
bool start = false;
|
||||||
|
|
||||||
|
if (msg[WD_MODE_CMD] == MODE_CMD_HEAD)
|
||||||
|
{
|
||||||
|
// omit unnecessary reconfiguration
|
||||||
|
if (L2_GetNodeType(linkInstPtr) != L2_NODE_HEAD)
|
||||||
|
{
|
||||||
|
// head node config
|
||||||
|
linkConfig.myType = L2_NODE_HEAD;
|
||||||
|
linkConfig.myId = 1;
|
||||||
|
reconfig = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (msg[WD_MODE_CMD] == MODE_CMD_MEMBER )
|
||||||
|
{
|
||||||
|
// omit unnecessary reconfiguration
|
||||||
|
if (L2_GetNodeType(linkInstPtr) != L2_NODE_MEMBER)
|
||||||
|
{
|
||||||
|
// member node config
|
||||||
|
linkConfig.myType = L2_NODE_MEMBER;
|
||||||
|
linkConfig.myId = 2;
|
||||||
|
reconfig = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Ignore current command
|
||||||
|
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
|
||||||
|
WD_MODE_CMD, msg[WD_MODE_CMD]);
|
||||||
|
return EPARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(msg[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER)
|
||||||
|
{
|
||||||
|
// high power config
|
||||||
|
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_FULL);
|
||||||
|
start = true;
|
||||||
|
}
|
||||||
|
else if(msg[WD_EN_CMD] == EN_CMD_ON_LOW_POWER)
|
||||||
|
{
|
||||||
|
// low power config
|
||||||
|
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_POWER_LOW);
|
||||||
|
start = true;
|
||||||
|
}
|
||||||
|
else if(msg[WD_EN_CMD] == EN_CMD_SILENT)
|
||||||
|
{
|
||||||
|
// silence config
|
||||||
|
// TODO: better approach?
|
||||||
|
start = false;
|
||||||
|
Linklayer_Halt(linkInstPtr);
|
||||||
|
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_STANDBY);
|
||||||
|
TIME_WORD pullTime = {0, 0};
|
||||||
|
pullTime.int_part = TimeCtrl_GetIntCnt(tmcRef) + 1;
|
||||||
|
if (Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL) != SUCCESS)
|
||||||
|
{
|
||||||
|
DBG_ERROR("Physical set pull time failed.\n");
|
||||||
|
}
|
||||||
|
Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL);
|
||||||
|
}
|
||||||
|
if (reconfig == true)
|
||||||
|
{
|
||||||
|
Linklayer_Reconfig(linkInstPtr, &linkConfig);
|
||||||
|
}
|
||||||
|
if (start == true)
|
||||||
|
{
|
||||||
|
Linklayer_Start(linkInstPtr);
|
||||||
|
}
|
||||||
|
instPtr->mpcLog.lastConfig[0] = msg[WD_MODE_CMD];
|
||||||
|
instPtr->mpcLog.lastConfig[1] = msg[WD_EN_CMD];
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Initialize MPC instance.
|
||||||
|
*
|
||||||
|
* @param InstPtr A double pointer to MPC instance.
|
||||||
|
* @param config A pointer to MPC configurations.
|
||||||
|
*
|
||||||
|
* @return None.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
int32_t Mpc_Init(MPC **instPtr, MPC_CONFIG *config)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
ASSERT(config != NULL);
|
||||||
|
MPC_HW_CONFIG mpcHwConfig;
|
||||||
|
int32_t Status;
|
||||||
|
(*instPtr) = malloc(sizeof(MPC));
|
||||||
|
if ((*instPtr) == NULL)
|
||||||
|
{
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
(*instPtr)->rxQueue = NULL;
|
||||||
|
(*instPtr)->txQueue = NULL;
|
||||||
|
(*instPtr)->mpchwDesc = NULL;
|
||||||
|
memcpy(&((*instPtr)->config), config, sizeof(MPC_CONFIG));
|
||||||
|
memset(&((*instPtr)->mpcLog), 0x00, sizeof(SYSBUSLOG));
|
||||||
|
memset(&((*instPtr)->linkLog), 0x00, sizeof(LINKLOG));
|
||||||
|
memset(&((*instPtr)->phyLog), 0x00, sizeof(PHYLOG));
|
||||||
|
memset(&((*instPtr)->hwState), 0x00, sizeof(HWSTATE));
|
||||||
|
|
||||||
|
XBram_Config *bramConfigPtr;
|
||||||
|
XBram mpcBram;
|
||||||
|
|
||||||
|
bramConfigPtr = XBram_LookupConfig(config->bramId);
|
||||||
|
if (bramConfigPtr == NULL)
|
||||||
|
{
|
||||||
|
Status = EDCONF;
|
||||||
|
goto mpc_init_error;
|
||||||
|
}
|
||||||
|
Status = XBram_CfgInitialize(&mpcBram, bramConfigPtr,
|
||||||
|
bramConfigPtr->CtrlBaseAddress);
|
||||||
|
if (Status != SUCCESS)
|
||||||
|
{
|
||||||
|
goto mpc_init_error;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Execute the BRAM driver selftest.
|
||||||
|
*/
|
||||||
|
Status = XBram_SelfTest(&mpcBram, 0);
|
||||||
|
if (Status != SUCCESS)
|
||||||
|
{
|
||||||
|
goto mpc_init_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpcHwConfig.txBuffAddr = mpcBram.Config.MemBaseAddress;
|
||||||
|
mpcHwConfig.rxBuffAddr = mpcBram.Config.MemBaseAddress;
|
||||||
|
mpcHwConfig.gpioId = config->gpioId;
|
||||||
|
|
||||||
|
Status = MpcHw_Init(&((*instPtr)->mpchwDesc), &mpcHwConfig);
|
||||||
|
if (Status != SUCCESS)
|
||||||
|
{
|
||||||
|
Status = ENOMEM;
|
||||||
|
goto mpc_init_error;
|
||||||
|
}
|
||||||
|
if (CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false)
|
||||||
|
{
|
||||||
|
Status = ENOMEM;
|
||||||
|
goto mpc_init_error;
|
||||||
|
}
|
||||||
|
if (CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false)
|
||||||
|
{
|
||||||
|
Status = ENOMEM;
|
||||||
|
goto mpc_init_error;
|
||||||
|
}
|
||||||
|
(*instPtr)->isEnable = false; // nothing received.
|
||||||
|
(*instPtr)->isRxDone = false; // nothing received.
|
||||||
|
(*instPtr)->isTxDone = true; // nothing to be sent.
|
||||||
|
return SUCCESS;
|
||||||
|
|
||||||
|
mpc_init_error:
|
||||||
|
free((*instPtr)->mpchwDesc);
|
||||||
|
free((*instPtr)->txQueue);
|
||||||
|
free((*instPtr)->rxQueue);
|
||||||
|
free(*instPtr);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Generate a remote test response message.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to MPC instance.
|
||||||
|
*
|
||||||
|
* @return SUCCESS
|
||||||
|
* error code
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
int32_t Mpc_PendRemoteTest(MPC *instPtr)
|
||||||
|
{
|
||||||
|
MPC_HW_FRAME *sysbusRsp;
|
||||||
|
uint8_t *msg;
|
||||||
|
if (instPtr->isEnable == false)
|
||||||
|
{
|
||||||
|
DBG_ERROR("System is not enabled!\n");
|
||||||
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
sysbusRsp = malloc(sizeof(MPC_HW_FRAME));
|
||||||
|
if (sysbusRsp == NULL) {
|
||||||
|
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
sysbusRsp = malloc(sizeof(MPC_HW_FRAME));
|
||||||
|
msg = sysbusRsp->data + FRAME_PAYLOAD_POFFSET;
|
||||||
|
sysbusRsp->len = RM_TEST_RESP_LEN;
|
||||||
|
if (L2_GetNodeType(linkInstPtr) == L2_NODE_HEAD)
|
||||||
|
{
|
||||||
|
// head node config
|
||||||
|
msg[WD_CMD] = CMD_FLJ_RM_TEST;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg[WD_CMD] = CMD_LJ_RM_TEST;
|
||||||
|
}
|
||||||
|
msg[WD_PRD] = MY_PRD_ID;
|
||||||
|
|
||||||
|
TIME_WORD tmWord;
|
||||||
|
uint64_t time;
|
||||||
|
TimeCtrl_GetCurrentTime(linkInstPtr->config.tmcInstPtr, &tmWord);
|
||||||
|
time = (uint64_t)tmWord.int_part * TIME_FRAC_MAX + tmWord.frac_part;
|
||||||
|
memcpy(msg + WD_TIME_STAMP, &time, WD_TIME_STAMP_LEN);
|
||||||
|
SysMonitor_GetLinklayerLog(&(instPtr->linkLog));
|
||||||
|
SysMonitor_GetPhysicalLayerLog(&(instPtr->phyLog));
|
||||||
|
SysMonitor_GetHardwareStatus(&(instPtr->hwState));
|
||||||
|
memcpy(msg + WD_SYSBUS_LOG, &(instPtr->mpcLog), WD_SYSBUS_LOG_LEN);
|
||||||
|
memcpy(msg + WD_LINK_LOG, &(instPtr->linkLog), WD_LINK_LOG_LEN);
|
||||||
|
memcpy(msg + WD_PHY_LOG, &(instPtr->phyLog), WD_PHY_LOG_LEN);
|
||||||
|
memcpy(msg + WD_HARDWARE_ST, &(instPtr->hwState.spFpgaVolt), WD_HARDWARE_ST_LEN);
|
||||||
|
|
||||||
|
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
|
||||||
|
free(sysbusRsp);
|
||||||
|
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
|
||||||
|
return EQUEUE;
|
||||||
|
}
|
||||||
|
instPtr->mpcLog.remoteCnt++;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief A handler function. This handler evaluate the message from system
|
||||||
|
* bus receive queue, and make appropriate response.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to MPC instance.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
int32_t Mpc_HandleCmd(MPC *instPtr)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
int32_t Status;
|
||||||
|
MPC_HW_FRAME *mpcReq;
|
||||||
|
uint8_t *reqMsg;
|
||||||
|
if (CircQueuePop(instPtr->rxQueue, (void **)(&mpcReq)) == false)
|
||||||
|
{
|
||||||
|
DBG_WARNING("SystemBus::Nothing to be handled.\n");
|
||||||
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
reqMsg = mpcReq->data + FRAME_PAYLOAD_POFFSET;
|
||||||
|
if (reqMsg[WD_PRD] != MY_PRD_ID && reqMsg[WD_PRD] != PRD_ALL)
|
||||||
|
{
|
||||||
|
DBG_WARNING("SystemBus::Production code mismatch!\n");
|
||||||
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (reqMsg[WD_CMD])
|
||||||
|
{
|
||||||
|
case CMD_CONFIG:
|
||||||
|
{
|
||||||
|
Status = Mpc_SystemConfig(instPtr, reqMsg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
DBG_ERROR("SystemBus::Unknown command code!\n");
|
||||||
|
Status = FAILURE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(mpcReq);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief This function send a repose frame from MPC tx queue.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to MPC instance.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
int32_t Mpc_MakeResp(MPC *instPtr)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
int32_t Status;
|
||||||
|
MPC_HW_FRAME *sysbusRsp;
|
||||||
|
if (CircQueuePop(instPtr->txQueue, (void **)(&sysbusRsp)) == false)
|
||||||
|
{
|
||||||
|
DBG_WARNING("SystemBus::Nothing to be sent.\n");
|
||||||
|
return EIGNORE;
|
||||||
|
}
|
||||||
|
instPtr->isTxDone = false; // A transmission procedure is started.
|
||||||
|
Status = MpcHw_Send(instPtr->mpchwDesc, sysbusRsp);
|
||||||
|
free(sysbusRsp);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief This function handles the mpc tx irq events.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to MPC instance.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
int32_t Mpc_TxIrqHandler(MPC *instPtr)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
// nothing special...
|
||||||
|
instPtr->isTxDone = true; // A transmission procedure finished.
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief This function handles the mpc rx irq events.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to MPC instance.
|
||||||
|
*
|
||||||
|
* @return None
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
int32_t Mpc_RxIrqHandler(MPC *instPtr)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
int32_t Status;
|
||||||
|
MPC_HW_FRAME *mpcReq;
|
||||||
|
instPtr->isRxDone = true; // whether reception successes or not, receiving procedure ended.
|
||||||
|
mpcReq = malloc(sizeof(MPC_HW_FRAME));
|
||||||
|
if (mpcReq == NULL)
|
||||||
|
{
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
Status = MpcHw_Recv(instPtr->mpchwDesc, mpcReq);
|
||||||
|
if (Status != SUCCESS)
|
||||||
|
{
|
||||||
|
goto recv_error;
|
||||||
|
}
|
||||||
|
if (CircQueuePush(instPtr->rxQueue, (void *)mpcReq) == false)
|
||||||
|
{
|
||||||
|
DBG_ERROR("SystemBus::RX Queue overflowed!\n");
|
||||||
|
Status = EQUEUE;
|
||||||
|
goto recv_error;
|
||||||
|
}
|
||||||
|
instPtr->isRxDone = false; // another reception is undergoing.
|
||||||
|
return SUCCESS;
|
||||||
|
recv_error:
|
||||||
|
free(mpcReq);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* Description: MPC protocol head file.
|
||||||
|
*
|
||||||
|
* Date: 2023-05-06 10:12
|
||||||
|
* Last Edit Time: [2023-05-06 10:13]
|
||||||
|
*
|
||||||
|
* Revisions: Rev 0.0
|
||||||
|
* History:
|
||||||
|
* [2023-05-06]: Initial version.
|
||||||
|
*
|
||||||
|
* Copyright(c) 2021 Beijing Institute of Technology.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __MPC_H_
|
||||||
|
#define __MPC_H_
|
||||||
|
|
||||||
|
/***************************** Include Files *********************************/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "mpc_hw.h" // MPC driver
|
||||||
|
#include "circ_queue.h"
|
||||||
|
#include "../system_monitor.h"
|
||||||
|
|
||||||
|
/************************** Constant Definitions *****************************/
|
||||||
|
/************************** Data Type Definitions ****************************/
|
||||||
|
// Definition of MPC instance.
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t bramId;
|
||||||
|
uint32_t gpioId;
|
||||||
|
uint32_t txQueueMax;
|
||||||
|
uint32_t rxQueueMax;
|
||||||
|
} MPC_CONFIG;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MPC_CONFIG config;
|
||||||
|
SYSBUSLOG mpcLog; // mpc log
|
||||||
|
LINKLOG linkLog; // Link layer log
|
||||||
|
PHYLOG phyLog; // Physical layer log
|
||||||
|
HWSTATE hwState; // Hardware status
|
||||||
|
MPC_HW *mpchwDesc;
|
||||||
|
CIRC_QUEUE *txQueue;
|
||||||
|
CIRC_QUEUE *rxQueue;
|
||||||
|
bool isEnable;
|
||||||
|
bool isRxDone;
|
||||||
|
bool isTxDone;
|
||||||
|
} MPC;
|
||||||
|
|
||||||
|
/************************** Function Prototypes ******************************/
|
||||||
|
|
||||||
|
int32_t Mpc_Init(MPC **instPtr, MPC_CONFIG *config);
|
||||||
|
|
||||||
|
int32_t Mpc_HandleCmd(MPC *instPtr);
|
||||||
|
int32_t Mpc_PendRemoteTest(MPC *instPtr);
|
||||||
|
int32_t Mpc_MakeResp(MPC *instPtr);
|
||||||
|
|
||||||
|
int32_t Mpc_TxIrqHandler(MPC *instPtr);
|
||||||
|
int32_t Mpc_RxIrqHandler(MPC *instPtr);
|
||||||
|
|
||||||
|
bool Mpc_IsEnable(MPC *instPtr);
|
||||||
|
|
||||||
|
bool Mpc_IsReqPending(MPC *instPtr);
|
||||||
|
bool Mpc_IsRsqPending(MPC *instPtr);
|
||||||
|
|
||||||
|
bool Mpc_IsTxBusy(MPC *instPtr);
|
||||||
|
bool Mpc_IsRxBusy(MPC *instPtr);
|
||||||
|
|
||||||
|
#endif //__MPC_H_
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* Description: MPC uart driver implementation file.
|
||||||
|
*
|
||||||
|
* Date: 2023-05-06 10:59
|
||||||
|
* LastEditTime: 2023-05-06 21:56
|
||||||
|
* Revisions: Rev 0.0
|
||||||
|
* History:
|
||||||
|
* [2023-05-06]: Initial version.
|
||||||
|
*
|
||||||
|
* Copyright(c) 2022 Beijing Institute of Technology.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/***************************** Include Files *******************************/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "mpc_hw.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
// Control and status register
|
||||||
|
#define MODULE_VERSION 0
|
||||||
|
#define MPC_STATUS 4
|
||||||
|
#define MPC_SEND_CMD 8
|
||||||
|
#define MPC_RECV_CNT 12
|
||||||
|
|
||||||
|
// Status code
|
||||||
|
#define MPC_STATUS_TX_BUSY 0x00010000
|
||||||
|
#define MPC_STATUS_RX_BUSY 0x01000000
|
||||||
|
// Data buffer register
|
||||||
|
#define MPC_TXBUFF_MAX 512
|
||||||
|
#define MPC_RXBUFF_MAX 512
|
||||||
|
|
||||||
|
// Frame Data offsets
|
||||||
|
#define FRAME_HEAD_LOW 0x02
|
||||||
|
#define FRAME_HEAD_HIGH 0x53
|
||||||
|
#define FRAME_TAIL_LOW 0x32
|
||||||
|
#define FRAME_TAIL_HIGH 0x20
|
||||||
|
|
||||||
|
#define FRAME_HEAD_LEN 2
|
||||||
|
#define FRAME_TAIL_LEN 2
|
||||||
|
#define FRAME_DUMMY_LEN 1 // Dummy
|
||||||
|
#define FRAME_OVERHEAD_LEN 2 // CheckSum, Dummy and
|
||||||
|
|
||||||
|
#define MPC_STATUS_CH 1
|
||||||
|
#define MPC_CONFIG_CH 2
|
||||||
|
|
||||||
|
#define MPC_CONFIG_SEND_TRIG 0x00000002
|
||||||
|
/*************************** Function Definitions ****************************/
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Instance initial
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to frame uart instance structure.
|
||||||
|
* @param config Base address of frame uart, refer to "xparameters.h"
|
||||||
|
*
|
||||||
|
* @return None.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
int MpcHw_Init(MPC_HW **instPtr, MPC_HW_CONFIG *config)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
ASSERT(config != NULL);
|
||||||
|
uint32_t Status;
|
||||||
|
(*instPtr) = malloc(sizeof(MPC_HW));
|
||||||
|
if ((*instPtr) == NULL)
|
||||||
|
{
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
(*instPtr)->config.txBuffAddr = config->txBuffAddr;
|
||||||
|
(*instPtr)->config.rxBuffAddr = config->rxBuffAddr;
|
||||||
|
Status = XGpio_Initialize(&((*instPtr)->gpioDesc), config->gpioId);
|
||||||
|
if (Status != SUCCESS) {
|
||||||
|
DBG_ERROR("MPC gpio Initialization Failed.\n");
|
||||||
|
free(*instPtr);
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
XGpio_SetDataDirection(&((*instPtr)->gpioDesc), MPC_CONFIG_CH, 0x00000000);
|
||||||
|
XGpio_SetDataDirection(&((*instPtr)->gpioDesc), MPC_STATUS_CH, 0xFFFFFFFF);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Send a MPC frame.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to MPC_HW instance structure.
|
||||||
|
* @param buff A pointer to send data buffer
|
||||||
|
* @param dLen A integer indicate the send data buffer length in byte.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
int MpcHw_Send(MPC_HW *instPtr, MPC_HW_FRAME *frame)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
ASSERT(frame != NULL);
|
||||||
|
uint8_t sendLen;
|
||||||
|
uint8_t *sendBuff = (uint8_t*) instPtr->config.txBuffAddr;
|
||||||
|
sendLen = frame->len + FRAME_OVERHEAD_LEN;
|
||||||
|
if (sendLen > MPC_TXBUFF_MAX || frame->len == 0)
|
||||||
|
{
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
frame->data[0] = FRAME_HEAD_LOW;
|
||||||
|
frame->data[1] = FRAME_HEAD_HIGH;
|
||||||
|
memcpy(sendBuff, frame->data, sendLen);
|
||||||
|
|
||||||
|
// Start Sending
|
||||||
|
uint32_t gpioVal = XGpio_DiscreteRead(&(instPtr->gpioDesc), MPC_CONFIG_CH);
|
||||||
|
gpioVal ^= MPC_CONFIG_SEND_TRIG;
|
||||||
|
XGpio_DiscreteWrite(&(instPtr->gpioDesc), MPC_CONFIG_CH, gpioVal);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* @brief Get last MPC frame.
|
||||||
|
*
|
||||||
|
* @param instPtr A pointer to MPC_HW instance structure.
|
||||||
|
* @param buff A pointer to receive data buffer.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
int MpcHw_Recv(MPC_HW *instPtr, MPC_HW_FRAME *frame)
|
||||||
|
{
|
||||||
|
ASSERT(instPtr != NULL);
|
||||||
|
ASSERT(frame != NULL);
|
||||||
|
uint8_t *recvBuff = (uint8_t *)(instPtr->config.rxBuffAddr);
|
||||||
|
memcpy(frame->data, recvBuff, MPC_FRAME_MAX);
|
||||||
|
frame->len = MPC_FRAME_MAX;
|
||||||
|
frame->isValid = true;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/**
|
||||||
|
* Description: MPC uart driver implementation file.
|
||||||
|
*
|
||||||
|
* Date: 2023-05-06 10:59
|
||||||
|
* LastEditTime: 2023-05-06 21:48
|
||||||
|
* Revisions: Rev 0.0
|
||||||
|
* History:
|
||||||
|
* [2023-05-06]: Initial version.
|
||||||
|
*
|
||||||
|
* Copyright(c) 2022 Beijing Institute of Technology.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef __MPC_HW_H
|
||||||
|
#define __MPC_HW_H
|
||||||
|
|
||||||
|
/**************************** Include Files *****************************/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "util.h"
|
||||||
|
#include "xgpio.h"
|
||||||
|
|
||||||
|
#define MPC_FRAME_MAX 256
|
||||||
|
#define FRAME_PAYLOAD_POFFSET 2 // CheckSum, Dummy and DataLen
|
||||||
|
/**************************** Type Definitions *****************************/
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Write a value to a SYSTEMBUS_UART register. A 32 bit write is performed.
|
||||||
|
* If the component is implemented in a smaller width, only the least
|
||||||
|
* significant data is written.
|
||||||
|
*
|
||||||
|
* @param baseAddr is the base address of the SYSTEMBUS_UARTdevice.
|
||||||
|
* @param offset is the register offset from the base to write to.
|
||||||
|
* @param data is the data written to the register.
|
||||||
|
*
|
||||||
|
* @return None.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* C-style signature:
|
||||||
|
* void MPC_HW_mWriteReg(uint32_t BaseAddress, unsigned RegOffset, uint32_t Data)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define MPC_HW_mWriteReg(baseAddr, offset, data) \
|
||||||
|
IO_Out32((baseAddr) + (offset), (uint32_t)(data))
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Read a value from a SYSTEMBUS_UART register. A 32 bit read is performed.
|
||||||
|
* If the component is implemented in a smaller width, only the least
|
||||||
|
* significant data is read from the register. The most significant data
|
||||||
|
* will be read as 0.
|
||||||
|
*
|
||||||
|
* @param baseAddr is the base address of the SYSTEMBUS_UART device.
|
||||||
|
* @param offset is the register offset from the base to write to.
|
||||||
|
*
|
||||||
|
* @return Data is the data from the register.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* C-style signature:
|
||||||
|
* uint32_t MPC_HW_mReadReg(uint32_t BaseAddress, unsigned RegOffset)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define MPC_HW_mReadReg(baseAddr, offset) \
|
||||||
|
IO_In32((baseAddr) + (offset))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uintptr_t txBuffAddr;
|
||||||
|
uintptr_t rxBuffAddr;
|
||||||
|
uint32_t gpioId;
|
||||||
|
} MPC_HW_CONFIG;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
MPC_HW_CONFIG config;
|
||||||
|
XGpio gpioDesc;
|
||||||
|
} MPC_HW;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t len;
|
||||||
|
uint8_t checkSum;
|
||||||
|
uint8_t isValid;
|
||||||
|
uint8_t data[MPC_FRAME_MAX];
|
||||||
|
} MPC_HW_FRAME;
|
||||||
|
|
||||||
|
/************************** Function Prototypes ******************************/
|
||||||
|
// Instance initial
|
||||||
|
int MpcHw_Init(MPC_HW **instPtr, MPC_HW_CONFIG *config);
|
||||||
|
|
||||||
|
// Send a MPC frame.
|
||||||
|
int MpcHw_Send(MPC_HW *instPtr, MPC_HW_FRAME *frame);
|
||||||
|
|
||||||
|
// Get last MPC frame.
|
||||||
|
int MpcHw_Recv(MPC_HW *instPtr, MPC_HW_FRAME *frame);
|
||||||
|
|
||||||
|
#endif // __MPC_HW_H
|
||||||
Reference in New Issue
Block a user