add MPC module to GE project
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user