650 lines
17 KiB
C
650 lines
17 KiB
C
/*****************************************************************************/
|
|
/**
|
|
* Description: System bus 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 "systembus_uart.h"
|
|
#include "systembus.h"
|
|
#include "util.h"
|
|
#include "common.h"
|
|
#include "error.h"
|
|
#include "circ_queue.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 0xDE
|
|
#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
|
|
// -- -- Signal processor voltage
|
|
#define WD_SP_VOLT 0x03
|
|
// -- -- Signal processor temperature
|
|
#define WD_SP_TEMP 0x04
|
|
// -- -- Signal processor chip status
|
|
#define WD_SP_CS 0x05
|
|
// -- -- Signal processor antenna voltage
|
|
#define WD_ANT_VOLT 0x06
|
|
// -- -- Signal processor antenna temperature
|
|
#define WD_ANT_TEMP 0x07
|
|
// -- -- Signal processor antenna PLL lock status
|
|
#define WD_ANT_PLL 0x08
|
|
// -- -- Signal processor antenna MGC
|
|
#define WD_ANT_MGC_L 0x09
|
|
#define WD_ANT_MGC_H 0x0A
|
|
// -- -- Signal processor antenna status
|
|
#define WD_ANT_ST 0x0B
|
|
// -- -- Dummy must be 0x00
|
|
#define WD_ST_DUMMY 0x0C
|
|
|
|
// Data Send Test Command
|
|
#define CMD_DATA_TEST_A 0xE2
|
|
// -- Request
|
|
#define DATA_TEST_REQ_A_LEN 80
|
|
// -- -- 78 byte payload
|
|
// -- Response
|
|
#define DATA_TEST_RSP_A_LEN 80
|
|
// -- -- 78 byte payload
|
|
|
|
// Data Send Test Command
|
|
#define CMD_DATA_TEST_B 0xF2
|
|
// -- Request
|
|
#define DATA_TEST_REQ_B_LEN 152
|
|
// -- -- 150 byte payload
|
|
// -- Response
|
|
#define DATA_TEST_RSP_B_LEN 152
|
|
// -- -- 150 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 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 78
|
|
// -- -- received 78 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 168
|
|
// -- -- received 156 byte payload
|
|
|
|
// Remote Test FLJ
|
|
#define CMD_FLJ_RM_TEST 0xE6
|
|
// -- Request
|
|
#define WD_FLJ_RM_TEST 0x02
|
|
#define FLJ_RM_TEST_CODE 0x99
|
|
// -- Response
|
|
#define FLJ_RM_TEST_RESP_LEN 158
|
|
|
|
// Remote Test LJ
|
|
#define CMD_LJ_RM_TEST 0xF6
|
|
// -- Request
|
|
#define WD_LJ_RM_TEST 0x02
|
|
#define LJ_RM_TEST_CODE 0x99
|
|
// -- Response
|
|
#define LJ_RM_TEST_RESP_LEN 158
|
|
|
|
|
|
// 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 SystemBus_IsReqPendding(SYSBUS *instPtr)
|
|
{
|
|
ASSERT(instPtr != NULL);
|
|
return (!isCircQueueEmpty(instPtr->rxQueue));
|
|
}
|
|
|
|
inline bool SystemBus_IsRsqPendding(SYSBUS *instPtr)
|
|
{
|
|
ASSERT(instPtr != NULL);
|
|
return (!isCircQueueEmpty(instPtr->txQueue));
|
|
}
|
|
|
|
inline bool SystemBus_IsTxBusy(SYSBUS *instPtr)
|
|
{
|
|
ASSERT(instPtr != NULL);
|
|
return (!instPtr->isTxDone);
|
|
}
|
|
inline bool SystemBus_IsRxBusy(SYSBUS *instPtr)
|
|
{
|
|
ASSERT(instPtr != NULL);
|
|
return SysbusUart_IsRxBusy(instPtr->uartInst);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* @brief Initialize System Bus instance.
|
|
*
|
|
* @param InstPtr A double pointer to System Bus instance.
|
|
* @param config A pointer to System Bus configurations.
|
|
*
|
|
* @return None.
|
|
*
|
|
******************************************************************************/
|
|
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config)
|
|
{
|
|
ASSERT(instPtr != NULL);
|
|
ASSERT(config != NULL);
|
|
SYSBUS_UART_CONFIG uartConfig;
|
|
int32_t Status;
|
|
(*instPtr) = malloc(sizeof(SYSBUS));
|
|
if ((*instPtr) == NULL)
|
|
{
|
|
return FAILURE;
|
|
}
|
|
(*instPtr)->rxQueue = NULL;
|
|
(*instPtr)->txQueue = NULL;
|
|
(*instPtr)->uartInst = NULL;
|
|
memcpy(&((*instPtr)->config), config, sizeof(SYSBUS_CONFIG));
|
|
uartConfig.baseAddr = config->baseAddr;
|
|
Status = SysbusUart_Init(&((*instPtr)->uartInst), &uartConfig);
|
|
if (Status != SUCCESS)
|
|
{
|
|
Status = ENOMEM;
|
|
goto sysbus_init_error;
|
|
}
|
|
if (CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false)
|
|
{
|
|
Status = ENOMEM;
|
|
goto sysbus_init_error;
|
|
}
|
|
if (CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false)
|
|
{
|
|
Status = ENOMEM;
|
|
goto sysbus_init_error;
|
|
}
|
|
(*instPtr)->isRxDone = false; // nothing received.
|
|
(*instPtr)->isTxDone = true; // nothing to be sent.
|
|
return SUCCESS;
|
|
|
|
sysbus_init_error:
|
|
free((*instPtr)->uartInst);
|
|
free((*instPtr)->txQueue);
|
|
free((*instPtr)->rxQueue);
|
|
free(*instPtr);
|
|
return Status;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* @brief A handler function. This handler evaluate the message from system
|
|
* bus receive queue, and make appropriate response.
|
|
*
|
|
* @param instPtr A pointer to System Bus instance.
|
|
*
|
|
* @return None
|
|
*
|
|
******************************************************************************/
|
|
int32_t SystemBus_HandleCmd(SYSBUS *instPtr)
|
|
{
|
|
ASSERT(instPtr != NULL);
|
|
int32_t Status;
|
|
SYSBUS_UART_FRAME *sysbusReq, *sysbusRsp;
|
|
uint8_t *data;
|
|
if (CircQueuePop(instPtr->rxQueue, (void **)(&sysbusReq)) == false)
|
|
{
|
|
DBG_WARNING("SystemBus::Nothing to be handled.\n");
|
|
return EIGNORE;
|
|
}
|
|
data = sysbusReq->data;
|
|
if (data[WD_PRD] != MY_PRD_ID && data[WD_PRD] != PRD_ALL)
|
|
{
|
|
DBG_WARNING("SystemBus::Production code mismatch!\n");
|
|
return EIGNORE;
|
|
}
|
|
switch (data[WD_CMD])
|
|
{
|
|
case CMD_SELF_TEST:
|
|
{
|
|
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
if (sysbusRsp == NULL) {
|
|
DBG_ERROR("Failed to allocate memory for SELF TEST Response!\n");
|
|
Status = ENOMEM;
|
|
break;
|
|
}
|
|
sysbusRsp->len = ST_RSP_LEN;
|
|
memset(sysbusRsp->data, 0x00, ST_RSP_LEN);
|
|
sysbusRsp->data[WD_CMD] = CMD_SELF_TEST;
|
|
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
|
|
|
|
// FIXME: run self-test and insert result
|
|
sysbusRsp->data[WD_ST_RET] = ST_RET_OK;
|
|
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
|
|
{
|
|
free(sysbusRsp);
|
|
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
|
|
Status = EQUEUE;
|
|
break;
|
|
}
|
|
Status = SUCCESS;
|
|
break;
|
|
}
|
|
case CMD_DATA_TEST_A:
|
|
{
|
|
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
if (sysbusRsp == NULL) {
|
|
DBG_ERROR("Failed to allocate memory for DATA TEST A Response!\n");
|
|
Status = ENOMEM;
|
|
break;
|
|
}
|
|
sysbusRsp->len = DATA_TEST_RSP_A_LEN;
|
|
memcpy(sysbusRsp->data, sysbusReq->data, DATA_TEST_RSP_A_LEN);
|
|
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
|
|
{
|
|
free(sysbusRsp);
|
|
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
|
|
Status = EQUEUE;
|
|
break;
|
|
}
|
|
Status = SUCCESS;
|
|
break;
|
|
}
|
|
case CMD_DATA_TEST_B:
|
|
{
|
|
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
if (sysbusRsp == NULL) {
|
|
DBG_ERROR("Failed to allocate memory for DATA TEST B Response!\n");
|
|
Status = ENOMEM;
|
|
break;
|
|
}
|
|
sysbusRsp->len = DATA_TEST_RSP_B_LEN;
|
|
memcpy(sysbusRsp->data, sysbusReq->data, DATA_TEST_RSP_B_LEN);
|
|
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
|
|
{
|
|
free(sysbusRsp);
|
|
DBG_ERROR("SystemBus::TX Queue overflowed!\n");
|
|
Status = EQUEUE;
|
|
break;
|
|
}
|
|
Status = SUCCESS;
|
|
break;
|
|
}
|
|
case CMD_CONFIG:
|
|
{
|
|
PHY_INST *phyRef = linkInstPtr->config.phyInstPtr;
|
|
TMC_INST *tmcRef = linkInstPtr->config.tmcInstPtr;
|
|
|
|
if (data[WD_MODE_CMD] == MODE_CMD_HEAD)
|
|
{
|
|
// head node config
|
|
linkConfig.myType = L2_NODE_HEAD;
|
|
linkConfig.myId = 1;
|
|
Linklayer_Reconfig(linkInstPtr, &linkConfig);
|
|
}
|
|
else if (data[WD_MODE_CMD] == MODE_CMD_MEMBER)
|
|
{
|
|
// member node config
|
|
linkConfig.myType = L2_NODE_MEMBER;
|
|
linkConfig.myId = 2;
|
|
Linklayer_Reconfig(linkInstPtr, &linkConfig);
|
|
}
|
|
else
|
|
{
|
|
// FIXME:
|
|
// Halt linklayer
|
|
Linklayer_Halt(linkInstPtr);
|
|
DBG_ERROR("Unexpected config command 0x%02X:0x%02X",
|
|
WD_MODE_CMD, data[WD_MODE_CMD]);
|
|
}
|
|
|
|
if(data[WD_EN_CMD] == EN_CMD_ON_HIGH_POWER)
|
|
{
|
|
// high power config
|
|
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_HIGH_POWER);
|
|
Linklayer_Start(linkInstPtr);
|
|
|
|
}
|
|
else if(data[WD_EN_CMD] == EN_CMD_ON_LOW_POWER)
|
|
{
|
|
// low power config
|
|
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_LOW_POWER);
|
|
Linklayer_Start(linkInstPtr);
|
|
}
|
|
else
|
|
{
|
|
// silence config
|
|
// TODO: better approach?
|
|
Linklayer_Halt(linkInstPtr);
|
|
Phy_AntConfigMode(phyRef, PHY_ANT_MODE_SILENT);
|
|
TIME_WORD pullTime = {0, 0};
|
|
pullTime.int_part = TimeCtrl_GetIntCnt(tmcRef) + 1;
|
|
Status = Phy_SetTimeWord(phyRef, &pullTime, PHY_TIME_WORD_POLL);
|
|
if (Status != SUCCESS)
|
|
{
|
|
DBG_ERROR("Physical set pull time failed, with error code: %" PRId32 ".\n", Status);
|
|
}
|
|
Phy_SetupNextSlot(phyRef, PHY_TOR_RX, L1_10KBPS_10MS_FRAME, NULL);
|
|
}
|
|
|
|
_nop_(); // for debug
|
|
Status = SUCCESS;
|
|
break;
|
|
}
|
|
case CMD_SYS_INFO:
|
|
{
|
|
SysMonitor_UpdateSysinfoRaw(data + SYS_INFO_OFFSET);
|
|
Status = SUCCESS;
|
|
break;
|
|
}
|
|
// TODO
|
|
case CMD_FLJ_SEND:
|
|
{
|
|
SysMonitor_UpdateSendPayloadFLJRaw(data + FLJ_DATA_OFFSET); // omit control info
|
|
break;
|
|
}
|
|
case CMD_LJ_SEND:
|
|
{
|
|
SysMonitor_UpdateSendPayloadLJRaw(data + LJ_DATA_OFFSET); // omit control info
|
|
break;
|
|
}
|
|
case CMD_FLJ_POLL:
|
|
{
|
|
if (data[WD_FLJ_POLL] != FLJ_POLL_CODE)
|
|
{
|
|
DBG_ERROR("SystemBus::Invalid roll call code!\n");
|
|
Status = EIGNORE;
|
|
break;
|
|
}
|
|
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
if (sysbusRsp == NULL) {
|
|
DBG_ERROR("Failed to allocate memory for FLJ POLL Response!\n");
|
|
Status = ENOMEM;
|
|
break;
|
|
}
|
|
sysbusRsp->len = FLJ_POLL_RESP_LEN;
|
|
sysbusRsp->data[WD_CMD] = WD_FLJ_POLL;
|
|
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
|
|
uint32_t dataId;
|
|
SysMonitor_GetRecvPayloadFLJRaw(sysbusRsp->data + FLJ_DATA_OFFSET, &dataId); // omit control info
|
|
if (dataId == DATA_ID_NONE)
|
|
{
|
|
memset(sysbusRsp->data + FLJ_DATA_OFFSET, 0xAA, PAYLOAD_FLJ);
|
|
}
|
|
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
|
|
{
|
|
free(sysbusRsp);
|
|
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
|
|
Status = EQUEUE;
|
|
break;
|
|
}
|
|
Status = SUCCESS;
|
|
break;
|
|
}
|
|
case CMD_LJ_POLL:
|
|
{
|
|
if (data[WD_LJ_POLL] != LJ_POLL_CODE)
|
|
{
|
|
DBG_WARNING("SystemBus::Invalid roll call code!\n");
|
|
Status = EIGNORE;
|
|
break;
|
|
}
|
|
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
if (sysbusRsp == NULL) {
|
|
DBG_ERROR("Failed to allocate memory for LJ POLL Response!\n");
|
|
Status = ENOMEM;
|
|
break;
|
|
}
|
|
sysbusRsp->len = LJ_POLL_RESP_LEN;
|
|
sysbusRsp->data[WD_CMD] = WD_LJ_POLL;
|
|
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
|
|
uint32_t dataId;
|
|
SysMonitor_GetRecvPayloadLJRaw(sysbusRsp->data + LJ_DATA_OFFSET, &dataId); // omit control info
|
|
if (dataId == DATA_ID_NONE)
|
|
{
|
|
memset(sysbusRsp->data + LJ_DATA_OFFSET, 0xAA, PAYLOAD_LJ);
|
|
}
|
|
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false)
|
|
{
|
|
free(sysbusRsp);
|
|
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
|
|
Status = EQUEUE;
|
|
break;
|
|
}
|
|
Status = SUCCESS;
|
|
break;
|
|
}
|
|
case CMD_FLJ_RM_TEST:
|
|
{
|
|
if (data[WD_FLJ_RM_TEST] != FLJ_RM_TEST_CODE)
|
|
{
|
|
DBG_WARNING("SystemBus::Invalid remote test code!\n");
|
|
Status = EIGNORE;
|
|
break;
|
|
}
|
|
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
if (sysbusRsp == NULL) {
|
|
DBG_ERROR("Failed to allocate memory for FLJ REMOTE TEST Response!\n");
|
|
Status = ENOMEM;
|
|
break;
|
|
}
|
|
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
sysbusRsp->len = FLJ_RM_TEST_RESP_LEN;
|
|
memset(sysbusRsp->data, 0x00, FLJ_RM_TEST_RESP_LEN);
|
|
sysbusRsp->data[WD_CMD] = CMD_FLJ_RM_TEST;
|
|
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
|
|
|
|
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
|
|
free(sysbusRsp);
|
|
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
|
|
Status = EQUEUE;
|
|
break;
|
|
}
|
|
Status = SUCCESS;
|
|
break;
|
|
}
|
|
case CMD_LJ_RM_TEST:
|
|
{
|
|
if (data[WD_LJ_RM_TEST] != LJ_RM_TEST_CODE)
|
|
{
|
|
DBG_WARNING("SystemBus::Invalid remote test code!\n");
|
|
Status = EIGNORE;
|
|
break;
|
|
}
|
|
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
if (sysbusRsp == NULL) {
|
|
DBG_ERROR("Failed to allocate memory for LJ REMOTE TEST Response!\n");
|
|
Status = ENOMEM;
|
|
break;
|
|
}
|
|
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
sysbusRsp->len = LJ_RM_TEST_RESP_LEN;
|
|
memset(sysbusRsp->data, 0x00, LJ_RM_TEST_RESP_LEN);
|
|
sysbusRsp->data[WD_CMD] = CMD_LJ_RM_TEST;
|
|
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
|
|
|
|
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
|
|
free(sysbusRsp);
|
|
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
|
|
Status = EQUEUE;
|
|
break;
|
|
}
|
|
Status = SUCCESS;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
DBG_ERROR("SystemBus::Unknown command code!\n");
|
|
break;
|
|
}
|
|
}
|
|
free(sysbusReq);
|
|
return Status;
|
|
}
|
|
|
|
int32_t SystemBus_FLJ_PeriodUpdate(SYSBUS *instPtr)
|
|
{
|
|
// TODO
|
|
return SUCCESS;
|
|
}
|
|
|
|
int32_t SystemBus_LJ_PeriodUpdate(SYSBUS *instPtr)
|
|
{
|
|
// TODO
|
|
return SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* @brief This function send a repose frame from system bus tx queue.
|
|
*
|
|
* @param instPtr A pointer to System Bus instance.
|
|
*
|
|
* @return None
|
|
*
|
|
******************************************************************************/
|
|
int32_t SystemBus_MakeResp(SYSBUS *instPtr)
|
|
{
|
|
ASSERT(instPtr != NULL);
|
|
int32_t Status;
|
|
SYSBUS_UART_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 = SysbusUart_Send(instPtr->uartInst, sysbusRsp);
|
|
free(sysbusRsp);
|
|
return Status;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* @brief This function handles the systembus tx irq events.
|
|
*
|
|
* @param instPtr A pointer to System Bus instance.
|
|
*
|
|
* @return None
|
|
*
|
|
******************************************************************************/
|
|
int32_t SystemBus_TxIntrHandler(SYSBUS *instPtr)
|
|
{
|
|
ASSERT(instPtr != NULL);
|
|
// nothing special...
|
|
instPtr->isTxDone = true; // A transmission procedure finished.
|
|
return SUCCESS;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/**
|
|
* @brief This function handles the systembus rx irq events.
|
|
*
|
|
* @param instPtr A pointer to System Bus instance.
|
|
*
|
|
* @return None
|
|
*
|
|
******************************************************************************/
|
|
int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr)
|
|
{
|
|
ASSERT(instPtr != NULL);
|
|
int32_t Status;
|
|
SYSBUS_UART_FRAME *sysbusReq;
|
|
instPtr->isRxDone = true; // whether reception successes or not, receiving procedure ended.
|
|
sysbusReq = malloc(sizeof(SYSBUS_UART_FRAME));
|
|
if (sysbusReq == NULL)
|
|
{
|
|
return ENOMEM;
|
|
}
|
|
Status = SysbusUart_Recv(instPtr->uartInst, sysbusReq);
|
|
if (Status != SUCCESS)
|
|
{
|
|
goto recv_error;
|
|
}
|
|
if (CircQueuePush(instPtr->rxQueue, (void *)sysbusReq) == 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(sysbusReq);
|
|
return Status;
|
|
}
|