502 lines
14 KiB
C
502 lines
14 KiB
C
/*
|
|
* Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
#include "queue.h"
|
|
#include "semphr.h"
|
|
#include <unistd.h>
|
|
#include "n200_eclic.h"
|
|
#include "n200_func.h"
|
|
#include "uart.h"
|
|
#include "common.h"
|
|
#include "riscv_encoding.h"
|
|
|
|
#include "mailbox-common.h"
|
|
#include "mailbox_soc.h"
|
|
#include "mailbox-irq.h"
|
|
#include "mailbox.h"
|
|
#include "mailbox-htbl.h"
|
|
#include "mailbox-api.h"
|
|
#include "mailbox-rpc-test.h"
|
|
|
|
#define MBTAG "AOCPU"
|
|
#define PRINT_DBG(...) //printf(__VA_ARGS__)
|
|
#define PRINT_ERR(...) printf(__VA_ARGS__)
|
|
#define PRINT(...) printf(__VA_ARGS__)
|
|
|
|
#define AO_MBOX_ONLY_SYNC 1
|
|
|
|
void *g_tbl_ao;
|
|
void *pvClientIdTab;
|
|
struct xClientMboxChan *pxReeMboxChan;
|
|
struct xClientMboxChan *pxTeeMboxChan;
|
|
#ifdef DSPA2AO_CHANNEL
|
|
struct xClientMboxChan *pxDspaMboxChan;
|
|
#endif
|
|
TaskHandle_t ReeMboxHandler;
|
|
TaskHandle_t TeeMboxHandler;
|
|
#ifdef DSPA2AO_CHANNEL
|
|
TaskHandle_t DspMboxHandler;
|
|
#endif
|
|
static uint32_t ulReeSyncTaskWake;
|
|
static uint32_t ulTeeSyncTaskWake;
|
|
#ifdef DSPA2AO_CHANNEL
|
|
static uint32_t ulDspSyncTaskWake;
|
|
#endif
|
|
struct mboxPackInfo syncReeMboxInfo;
|
|
struct mboxPackInfo syncTeeMboxInfo;
|
|
#ifdef DSPA2AO_CHANNEL
|
|
struct mboxPackInfo syncDspMboxInfo;
|
|
#endif
|
|
|
|
static void vGetPayload(uint32_t addr, void *data, size_t size)
|
|
{
|
|
VALID_BUFFER_SIZE(size);
|
|
|
|
PRINT_DBG("get payload: addr:0x%x\n", (unsigned int)addr);
|
|
if (data != NULL)
|
|
vMboxRead(data, addr, size);
|
|
}
|
|
|
|
static void prvBuildPayload(uint32_t addr, void *data, size_t size)
|
|
{
|
|
VALID_BUFFER_SIZE(size);
|
|
|
|
PRINT_DBG("%s: addr:0x%x\n", __func__, (unsigned int)addr);
|
|
if (data != NULL)
|
|
vMboxWrite(addr, data, size);
|
|
}
|
|
|
|
static void vMboxHandleIsr(void)
|
|
{
|
|
uint64_t val = 0;
|
|
uint64_t ulIrqMask = IRQ_MASK;
|
|
int i = 0;
|
|
uint64_t ulIrqBitHandled = 0;
|
|
|
|
val = xGetMbIrqStats();
|
|
PRINT_DBG("[%s]: mb isr: 0x%llx\n", MBTAG, val);
|
|
val &= ulIrqMask;
|
|
while (val) {
|
|
for (i = 0; i < IRQ_MAX; i++) {
|
|
if (val & (1ULL << i)) {
|
|
if (xMbHandlerTable[i].vHandler != NULL)
|
|
xMbHandlerTable[i].vHandler(xMbHandlerTable[i].vArg);
|
|
}
|
|
}
|
|
ulIrqBitHandled |= val;
|
|
val = xGetMbIrqStats();
|
|
val &= ulIrqMask;
|
|
val = val ^ (ulIrqBitHandled & val);
|
|
PRINT_DBG("[%s]: mb isr: 0x%llx\n", MBTAG, val);
|
|
}
|
|
}
|
|
//DECLARE_IRQ(IRQ_NUM_MB_4, vMboxHandleIsr)
|
|
|
|
/* Remote to AOCPU mailbox handler */
|
|
static void vAoRevMboxHandler(void *vArg)
|
|
{
|
|
BaseType_t xYieldRequired = pdFALSE;
|
|
uint8_t mbox = (uintptr_t)vArg;
|
|
struct mboxPackInfo mbInfo = {0};
|
|
union MbStat_in st_in;
|
|
uint32_t ulMbCmd, ulSize, ulSync;
|
|
uint32_t ulRdAddr = 0;
|
|
uint32_t ulClrAddr = 0;
|
|
|
|
vDisableMbInterrupt(IRQ_REV_BIT(mbox));
|
|
st_in.reg = 0;
|
|
switch (mbox) {
|
|
case REE2AO_CHANNEL:
|
|
st_in.reg = REG32(pxReeMboxChan->pxMboxChan->ulStatAddr);
|
|
ulRdAddr = pxReeMboxChan->pxMboxChan->ulRdAddr;
|
|
ulClrAddr = pxReeMboxChan->pxMboxChan->ulClrAddr;
|
|
break;
|
|
case TEE2AO_CHANNEL:
|
|
st_in.reg = REG32(pxTeeMboxChan->pxMboxChan->ulStatAddr);
|
|
ulRdAddr = pxTeeMboxChan->pxMboxChan->ulRdAddr;
|
|
ulClrAddr = pxTeeMboxChan->pxMboxChan->ulClrAddr;
|
|
break;
|
|
#ifdef DSPA2AO_CHANNEL
|
|
case DSPA2AO_CHANNEL:
|
|
st_in.reg = REG32(pxDspaMboxChan->pxMboxChan->ulStatAddr);
|
|
ulRdAddr = pxDspaMboxChan->pxMboxChan->ulRdAddr;
|
|
ulClrAddr = pxDspaMboxChan->pxMboxChan->ulClrAddr;
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
if (st_in.reg == 0 || ulRdAddr == 0) {
|
|
PRINT_ERR("[%s] invalid mbox status or address!\n", MBTAG);
|
|
vClrMboxStats(ulClrAddr);
|
|
vClrMbInterrupt(IRQ_REV_BIT(mbox));
|
|
vEnableMbInterrupt(IRQ_REV_BIT(mbox));
|
|
return;
|
|
}
|
|
|
|
ulMbCmd = st_in.st.cmd;
|
|
ulSize = st_in.st.size;
|
|
ulSync = st_in.st.sync;
|
|
PRINT_DBG("[%s]:Rev Handler 0x%x, 0x%x, 0x%x\n", MBTAG, ulMbCmd, ulSize, ulSync);
|
|
|
|
if (ulMbCmd == 0) {
|
|
PRINT_ERR("[%s]:Err: mbox cmd is 0\n", MBTAG);
|
|
vClrMboxStats(ulClrAddr);
|
|
vClrMbInterrupt(IRQ_REV_BIT(mbox));
|
|
vEnableMbInterrupt(IRQ_REV_BIT(mbox));
|
|
return;
|
|
}
|
|
|
|
if (ulSize != 0)
|
|
vGetPayload(ulRdAddr, &mbInfo.mbdata, ulSize);
|
|
|
|
PRINT_DBG("%s taskid: 0x%llx\n", MBTAG, mbInfo.mbdata.taskid);
|
|
PRINT_DBG("%s complete: 0x%llx\n", MBTAG, mbInfo.mbdata.complete);
|
|
PRINT_DBG("%s ullclt: 0x%llx\n", MBTAG, mbInfo.mbdata.ullclt);
|
|
|
|
switch (ulSync) {
|
|
case MB_SYNC:
|
|
if (ulReeSyncTaskWake && (REE2AO_CHANNEL == mbox)) {
|
|
PRINT_ERR("ulReeSyncTaskWake Busy\n");
|
|
break;
|
|
}
|
|
if (ulTeeSyncTaskWake && (TEE2AO_CHANNEL == mbox)) {
|
|
PRINT_ERR("ulTeeSyncTaskWake Busy\n");
|
|
break;
|
|
}
|
|
#ifdef DSPA2AO_CHANNEL
|
|
if (ulDspSyncTaskWake && (DSPA2AO_CHANNEL == mbox)) {
|
|
PRINT_ERR("ulDspSyncTaskWake Busy\n");
|
|
break;
|
|
}
|
|
#endif
|
|
PRINT_DBG("[%s]: SYNC\n", MBTAG);
|
|
mbInfo.ulCmd = ulMbCmd;
|
|
mbInfo.ulSize = ulSize;
|
|
if (REE2AO_CHANNEL == mbox) {
|
|
syncReeMboxInfo = mbInfo;
|
|
ulReeSyncTaskWake = 1;
|
|
vTaskNotifyGiveFromISR(ReeMboxHandler, &xYieldRequired);
|
|
}
|
|
if (TEE2AO_CHANNEL == mbox) {
|
|
syncTeeMboxInfo = mbInfo;
|
|
ulTeeSyncTaskWake = 1;
|
|
vTaskNotifyGiveFromISR(TeeMboxHandler, &xYieldRequired);
|
|
}
|
|
#ifdef DSPA2AO_CHANNEL
|
|
if (DSPA2AO_CHANNEL == mbox) {
|
|
syncDspMboxInfo = mbInfo;
|
|
ulDspSyncTaskWake = 1;
|
|
vTaskNotifyGiveFromISR(DspMboxHandler, &xYieldRequired);
|
|
}
|
|
#endif
|
|
portYIELD_FROM_ISR(xYieldRequired);
|
|
break;
|
|
case MB_ASYNC:
|
|
#ifdef AO_MBOX_ONLY_SYNC
|
|
PRINT_DBG("[%s]: ASYNC no support\n", MBTAG);
|
|
vClrMboxStats(ulClrAddr);
|
|
vClrMbInterrupt(IRQ_REV_BIT(mbox));
|
|
vEnableMbInterrupt(IRQ_REV_BIT(mbox));
|
|
#endif
|
|
break;
|
|
default:
|
|
PRINT_ERR("[%s]: Not SYNC or ASYNC, Fail\n", MBTAG);
|
|
vClrMboxStats(ulClrAddr);
|
|
vClrMbInterrupt(IRQ_REV_BIT(mbox));
|
|
vEnableMbInterrupt(IRQ_REV_BIT(mbox));
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifdef CONFIG_MAILBOX_SEND
|
|
/* AOCPU to remote mailbox ACK handler */
|
|
static void vAoAckMboxHandler(void *vArg)
|
|
{
|
|
uint32_t mbox = (uintptr_t)vArg;
|
|
uint32_t addr = ulRevAddrMbox(mbox);
|
|
struct mbHeadInfo mbHead;
|
|
BaseType_t xYieldRequired = pdFALSE;
|
|
|
|
vDisableMbInterrupt(IRQ_SENDACK_BIT(mbox));
|
|
PRINT_DBG("[%s]: AO ACK handler, mboxid = %d\n", MBTAG,
|
|
(unsigned int)mbox);
|
|
xGetPayloadHead(addr, &mbHead);
|
|
if (mbHead.taskid)
|
|
vTaskNotifyGiveFromISR((TaskHandle_t)((uint32_t)mbHead.taskid), &xYieldRequired);
|
|
vClrMbInterrupt(IRQ_SENDACK_BIT(mbox));
|
|
vEnableMbInterrupt(IRQ_SENDACK_BIT(mbox));
|
|
portYIELD_FROM_ISR(xYieldRequired);
|
|
}
|
|
#endif
|
|
|
|
/* REE to AOCPU mailbox handle task on sync mode */
|
|
static void vReeSyncTask(void *pvParameters)
|
|
{
|
|
uint32_t ulWrAddr;
|
|
uint32_t ulClrAddr;
|
|
uint8_t ucMboxChId;
|
|
int index = 0;
|
|
|
|
(void)pvParameters;
|
|
ulWrAddr = pxReeMboxChan->pxMboxChan->ulWrAddr;
|
|
ulClrAddr = pxReeMboxChan->pxMboxChan->ulClrAddr;
|
|
ucMboxChId = pxReeMboxChan->pxMboxChan->ucMboxChId;
|
|
|
|
while (1) {
|
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
|
PRINT_DBG("[%s]:ReeSyncTask\n", MBTAG);
|
|
|
|
index = mailbox_htbl_invokeCmd(g_tbl_ao, syncReeMboxInfo.ulCmd,
|
|
syncReeMboxInfo.mbdata.data);
|
|
PRINT_DBG("[%s]:mbox:%d\n", MBTAG, ucMboxChId);
|
|
if (index != 0) {
|
|
if (index == MAX_ENTRY_NUM) {
|
|
memset(&syncReeMboxInfo.mbdata.data, 0,
|
|
sizeof(syncReeMboxInfo.mbdata.data));
|
|
syncReeMboxInfo.mbdata.status = ACK_FAIL;
|
|
if (ulWrAddr)
|
|
prvBuildPayload(ulWrAddr, &syncReeMboxInfo.mbdata,
|
|
sizeof(syncReeMboxInfo.mbdata));
|
|
PRINT_DBG("[%s]: undefine cmd or no callback\n", MBTAG);
|
|
} else {
|
|
PRINT_DBG("[%s]:ReeSync re len:%d\n", MBTAG,
|
|
sizeof(syncReeMboxInfo.mbdata));
|
|
syncReeMboxInfo.mbdata.status = ACK_OK;
|
|
if (ulWrAddr)
|
|
prvBuildPayload(ulWrAddr, &syncReeMboxInfo.mbdata,
|
|
sizeof(syncReeMboxInfo.mbdata));
|
|
}
|
|
}
|
|
|
|
vEnterCritical();
|
|
PRINT_DBG("[%s]:ReeSync clear mbox:%d\n", MBTAG, ucMboxChId);
|
|
ulReeSyncTaskWake = 0;
|
|
vClrMboxStats(ulClrAddr);
|
|
vClrMbInterrupt(IRQ_REV_BIT(ucMboxChId));
|
|
vEnableMbInterrupt(IRQ_REV_BIT(ucMboxChId));
|
|
vExitCritical();
|
|
}
|
|
}
|
|
|
|
/* TEE to AOCPU mailbox handle task on sync mode */
|
|
static void vTeeSyncTask(void *pvParameters)
|
|
{
|
|
uint32_t ulWrAddr;
|
|
uint32_t ulClrAddr;
|
|
uint8_t ucMboxChId;
|
|
int index = 0;
|
|
|
|
(void)pvParameters;
|
|
ulWrAddr = pxTeeMboxChan->pxMboxChan->ulWrAddr;
|
|
ulClrAddr = pxTeeMboxChan->pxMboxChan->ulClrAddr;
|
|
ucMboxChId = pxTeeMboxChan->pxMboxChan->ucMboxChId;
|
|
|
|
while (1) {
|
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
|
PRINT_DBG("[%s]:TeeSyncTask\n", MBTAG);
|
|
|
|
index = mailbox_htbl_invokeCmd(g_tbl_ao, syncTeeMboxInfo.ulCmd,
|
|
syncTeeMboxInfo.mbdata.data);
|
|
PRINT_DBG("[%s]:mbox:%d\n", MBTAG, ucMboxChId);
|
|
if (index != 0) {
|
|
if (index == MAX_ENTRY_NUM) {
|
|
pvMboxMemSet(&syncTeeMboxInfo.mbdata.data, 0,
|
|
sizeof(syncTeeMboxInfo.mbdata.data));
|
|
syncTeeMboxInfo.mbdata.status = ACK_FAIL;
|
|
if (ulWrAddr)
|
|
prvBuildPayload(ulWrAddr, &syncTeeMboxInfo.mbdata,
|
|
sizeof(syncTeeMboxInfo.mbdata));
|
|
PRINT_DBG("[%s]: undefine cmd or no callback\n", MBTAG);
|
|
} else {
|
|
PRINT_DBG("[%s]:TeeSync re len:%d\n", MBTAG,
|
|
sizeof(syncTeeMboxInfo.mbdata));
|
|
syncTeeMboxInfo.mbdata.status = ACK_OK;
|
|
if (ulWrAddr)
|
|
prvBuildPayload(ulWrAddr, &syncTeeMboxInfo.mbdata,
|
|
sizeof(syncTeeMboxInfo.mbdata));
|
|
}
|
|
}
|
|
|
|
vEnterCritical();
|
|
PRINT_DBG("[%s]:TeeSync clear mbox:%d\n", MBTAG, ucMboxChId);
|
|
ulTeeSyncTaskWake = 0;
|
|
vClrMboxStats(ulClrAddr);
|
|
vClrMbInterrupt(IRQ_REV_BIT(ucMboxChId));
|
|
vEnableMbInterrupt(IRQ_REV_BIT(ucMboxChId));
|
|
vExitCritical();
|
|
}
|
|
}
|
|
|
|
#ifdef DSPA2AO_CHANNEL
|
|
/* DSP to AOCPU mailbox handle task on sync mode */
|
|
static void vDspSyncTask(void *pvParameters)
|
|
{
|
|
uint32_t ulWrAddr;
|
|
uint32_t ulClrAddr;
|
|
uint8_t ucMboxChId;
|
|
int index = 0;
|
|
|
|
(void)pvParameters;
|
|
ulWrAddr = pxDspaMboxChan->pxMboxChan->ulWrAddr;
|
|
ulClrAddr = pxDspaMboxChan->pxMboxChan->ulClrAddr;
|
|
ucMboxChId = pxDspaMboxChan->pxMboxChan->ucMboxChId;
|
|
|
|
while (1) {
|
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
|
PRINT_DBG("[%s]:DspSyncTask\n", MBTAG);
|
|
|
|
index = mailbox_htbl_invokeCmd(g_tbl_ao, syncDspMboxInfo.ulCmd,
|
|
syncDspMboxInfo.mbdata.data);
|
|
PRINT_DBG("[%s]:mbox:%d\n", MBTAG, ucMboxChId);
|
|
if (index != 0) {
|
|
if (index == MAX_ENTRY_NUM) {
|
|
memset(&syncDspMboxInfo.mbdata.data, 0,
|
|
sizeof(syncDspMboxInfo.mbdata.data));
|
|
syncDspMboxInfo.mbdata.status = ACK_FAIL;
|
|
if (ulWrAddr)
|
|
prvBuildPayload(ulWrAddr, &syncDspMboxInfo.mbdata,
|
|
sizeof(syncDspMboxInfo.mbdata));
|
|
PRINT_DBG("[%s]: undefine cmd or no callback\n", MBTAG);
|
|
} else {
|
|
PRINT_DBG("[%s]:DspSync re len:%d\n", MBTAG,
|
|
sizeof(syncDspMboxInfo.mbdata));
|
|
syncDspMboxInfo.mbdata.status = ACK_OK;
|
|
if (ulWrAddr)
|
|
prvBuildPayload(ulWrAddr, &syncDspMboxInfo.mbdata,
|
|
sizeof(syncDspMboxInfo.mbdata));
|
|
}
|
|
}
|
|
|
|
vEnterCritical();
|
|
PRINT_DBG("[%s]:DspSync clear mbox:%d\n", MBTAG, ucMboxChId);
|
|
ulDspSyncTaskWake = 0;
|
|
vClrMboxStats(ulClrAddr);
|
|
vClrMbInterrupt(IRQ_REV_BIT(ucMboxChId));
|
|
vEnableMbInterrupt(IRQ_REV_BIT(ucMboxChId));
|
|
vExitCritical();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
int iMboxInit(void)
|
|
{
|
|
int ret;
|
|
|
|
PRINT("[%s]: mbox init\n", MBTAG);
|
|
mailbox_htbl_init(&g_tbl_ao);
|
|
iMboxClientIdTabInit(&pvClientIdTab);
|
|
|
|
/* Request mailbox channel for remote core to AOCPU */
|
|
pxReeMboxChan = xMboxRequestChan(REE2AO_DRV);
|
|
pxTeeMboxChan = xMboxRequestChan(TEE2AO_DRV);
|
|
#ifdef DSPA2AO_CHANNEL
|
|
pxDspaMboxChan = xMboxRequestChan(DSPA2AO_DRV);
|
|
#endif
|
|
|
|
/* Set MBOX IRQ Handler and Priority */
|
|
vSetMbIrqHandler(IRQ_REV_NUM(REE2AO_CHANNEL), vAoRevMboxHandler,
|
|
(void *)REE2AO_CHANNEL, 10);
|
|
|
|
vSetMbIrqHandler(IRQ_REV_NUM(TEE2AO_CHANNEL), vAoRevMboxHandler,
|
|
(void *)TEE2AO_CHANNEL, 10);
|
|
|
|
#ifdef CONFIG_MAILBOX_SEND
|
|
vSetMbIrqHandler(IRQ_SENDACK_NUM(AO2REE_CHANNEL), vAoAckMboxHandler,
|
|
(void *)AO2REE_CHANNEL, 10);
|
|
#endif
|
|
|
|
#ifdef DSPA2AO_CHANNEL
|
|
vSetMbIrqHandler(IRQ_REV_NUM(DSPA2AO_CHANNEL), vAoRevMboxHandler,
|
|
(void *)DSPA2AO_CHANNEL, 10);
|
|
#ifdef CONFIG_MAILBOX_SEND
|
|
vSetMbIrqHandler(IRQ_SENDACK_NUM(AO2DSPA_CHANNEL), vAoAckMboxHandler,
|
|
(void *)AO2DSPA_CHANNEL, 10);
|
|
#endif
|
|
#endif
|
|
|
|
/* Register and enable mailbox IRQ */
|
|
RegisterIrq(MAILBOX_AOCPU_IRQ, 6, vMboxHandleIsr);
|
|
EnableIrq(MAILBOX_AOCPU_IRQ);
|
|
|
|
xTaskCreate(vReeSyncTask, "AOReeSyncTask", configMINIMAL_STACK_SIZE,
|
|
0, TASK_PRIORITY, (TaskHandle_t *)&ReeMboxHandler);
|
|
|
|
xTaskCreate(vTeeSyncTask, "AOTeeSyncTask", configMINIMAL_STACK_SIZE,
|
|
0, TASK_PRIORITY, (TaskHandle_t *)&TeeMboxHandler);
|
|
|
|
#ifdef DSPA2AO_CHANNEL
|
|
xTaskCreate(vDspSyncTask, "AODspSyncTask", configMINIMAL_STACK_SIZE,
|
|
0, TASK_PRIORITY, (TaskHandle_t *)&DspMboxHandler);
|
|
#endif
|
|
|
|
#ifdef CONFIG_MAILBOX_SEND
|
|
vInitMboxChLock();
|
|
#endif
|
|
ret = vRpcUserCmdInit();
|
|
|
|
PRINT("[%s]: mbox init end\n", MBTAG);
|
|
return ret;
|
|
}
|
|
|
|
#ifdef CONFIG_MAILBOX_SEND
|
|
int iMboxTransData(struct xClientMboxChan *pxChan, struct xMboxData *pxData)
|
|
{
|
|
struct mboxData xMboxData;
|
|
uint32_t ulSize;
|
|
union MbStat_in xMboxStatIn;
|
|
struct MbStat *pxMboxStat;
|
|
uint32_t ulVal = 0;
|
|
uint8_t ucChId;
|
|
uint8_t ucClientId;
|
|
int iRet = 0;
|
|
|
|
ucClientId = pxChan->ucClientChId;
|
|
ucChId = pxChan->pxMboxChan->ucMboxChId;
|
|
SEND_VALID_CHANNEL(ucChId);
|
|
PRINT_DBG("[%s]: mboxid = %d\n", MBTAG, ucChId);
|
|
PRINT_DBG("[%s]: cmd = 0x%x\n", MBTAG, (unsigned int)pxData->ulCmd);
|
|
PRINT_DBG("[%s]: set_addr = 0x%x\n", MBTAG,
|
|
(unsigned int)pxChan->pxMboxChan->ulSetAddr);
|
|
|
|
xMuteLock(pxChan->pxMboxChan->xLock);
|
|
ulSize = pxData->ucTxSize + sizeof(struct mbHeadInfo);
|
|
pxMboxStat = &xMboxStatIn.st;
|
|
pxMboxStat->cmd = pxData->ulCmd;
|
|
pxMboxStat->size = ulSize;
|
|
pxMboxStat->sync = MB_ASYNC;
|
|
memcpy((char *)xMboxData.data, pxData->pvTxbuf, pxData->ucTxSize);
|
|
xMboxData.taskid = (uint32_t)(void *)xTaskGetCurrentTaskHandle();
|
|
xMboxData.status = ucClientId;
|
|
xMboxData.complete = 0;
|
|
prvBuildPayload(pxChan->pxMboxChan->ulWrAddr, &xMboxData, ulSize);
|
|
PRINT_DBG("[%s]: set command 0x%x\n", MBTAG, pxMboxStat->cmd);
|
|
vSetMboxStats(pxChan->pxMboxChan->ulSetAddr, xMboxStatIn.st);
|
|
ulVal = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(3000));
|
|
if (ulVal == 0) {
|
|
PRINT_ERR("[%s]:Err: mbox XEFR msg TMO!\n", MBTAG);
|
|
xMboxData.taskid = 0;
|
|
xMboxData.status = 0;
|
|
prvBuildPayload(pxChan->pxMboxChan->ulWrAddr, &xMboxData, ulSize);
|
|
xMboxStatIn.reg = 0;
|
|
vSetMboxStats(pxChan->pxMboxChan->ulSetAddr, xMboxStatIn.st);
|
|
iRet = ERR_MBOX(ETIME);
|
|
} else {
|
|
PRINT_DBG("[%s]: task wait ACK done\n", MBTAG);
|
|
iRet = pdTRUE;
|
|
}
|
|
xMuteUnlock(pxChan->pxMboxChan->xLock);
|
|
|
|
return iRet;
|
|
}
|
|
#endif
|