/* Copyright (c) 2017, Texas Instruments Incorporated - http://www.ti.com/ All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include "aspMsg_common.h" #include "aspMsg_master.h" #include "audioStreamProc_common.h" #include "common.h" #define AspMsg_MasterToSlaveMsgHeapId ( 0 ) AspMsgMaster_Module gAspMsgMaster; AspMsgMaster_Handle hAspMsgMaster=&gAspMsgMaster; Uint32 gMessageId; /* Initialize ASP master messaging */ Int AspMsgMaster_init( AspMsgMaster_Handle hAspMsgMaster, UInt16 remoteProcId, UInt16 numMsgs ) { Int status = ASP_MSG_MASTER_SOK; Int align; Error_Block eb; IHeap_Handle srHeap; HeapBuf_Params heapParams; MessageQ_Params msgqParams; char msgqName[32]; UInt16 regionId; Log_print0(Diags_ENTRY, "AspMsgMaster_init(): -->"); Log_info0("AspMsgMaster_init(): -->"); // set default values hAspMsgMaster->masterQue = NULL; hAspMsgMaster->slaveQue = MessageQ_INVALIDMESSAGEQ; hAspMsgMaster->heapId = AspMsg_MasterToSlaveMsgHeapId; hAspMsgMaster->msgSize = 0; hAspMsgMaster->messageId = 0; // set processor Ids hAspMsgMaster->masterProcId = MultiProc_self(); hAspMsgMaster->slaveProcId = remoteProcId; regionId = SharedRegion_getIdByName("SR_0"); // get IPC shared region Id // compute message size to fill entire cache lines align = SharedRegion_getCacheLineSize(regionId); hAspMsgMaster->msgSize = ROUNDUP(sizeof(ASP_Msg), align); // compute message pool size hAspMsgMaster->poolSize = hAspMsgMaster->msgSize * numMsgs; // acquire message pool memory srHeap = (IHeap_Handle)SharedRegion_getHeap(regionId); hAspMsgMaster->store = Memory_alloc(srHeap, hAspMsgMaster->poolSize, align, NULL); // create a heap in shared memory for message pool HeapBuf_Params_init(&heapParams); heapParams.blockSize = hAspMsgMaster->msgSize; heapParams.numBlocks = numMsgs; heapParams.bufSize = hAspMsgMaster->poolSize; heapParams.align = align; heapParams.buf = hAspMsgMaster->store; Error_init(&eb); hAspMsgMaster->heap = HeapBuf_create(&heapParams, &eb); if (hAspMsgMaster->heap == NULL) { Log_error0("AspMsgMaster_init(): failed creating message pool"); status = ASP_MSG_MASTER_HEAPBUF_CREATE_FAIL; Log_print1(Diags_INFO, "AspMsgMaster_init(): <-- status=%d", (IArg)status); return status; } // bind message pool to heapId status = MessageQ_registerHeap((Ptr)(hAspMsgMaster->heap), hAspMsgMaster->heapId); if (status != MessageQ_S_SUCCESS) { Log_error0("AspMsgMaster_init(): failed registering heap"); status = ASP_MSG_MASTER_MSGQ_REGHEAP_FAIL; Log_print1(Diags_INFO, "AspMsgMaster_init(): <-- status=%d", (IArg)status); return status; } // create local message queue (inbound messages) MessageQ_Params_init(&msgqParams); hAspMsgMaster->masterQue = MessageQ_create(NULL, &msgqParams); if (hAspMsgMaster->masterQue == NULL) { Log_error0("AspMsgMaster_init(): failed creating MessageQ"); status = ASP_MSG_MASTER_MASTER_MSGQ_CREATE_FAIL; Log_print1(Diags_INFO, "AspMsgMaster_init(): <-- status=%d", (IArg)status); return status; } // open the remote message queue System_sprintf(msgqName, AspMsg_SlaveMsgQueName, MultiProc_getName(remoteProcId)); Log_info0("AspMsgMaster_init(): MessageQ_open() start"); do { status = MessageQ_open(msgqName, &hAspMsgMaster->slaveQue); Log_info1("MessageQ_open() status=%d", status); //Task_sleep(1); } while (status == MessageQ_E_NOTFOUND); Log_info0("AspMsgMaster_init(): MessageQ_open() finish"); if (status < 0) { Log_error0("AspMsgMaster_init(): failed opening MessageQ"); status = ASP_MSG_MASTER_SLAVE_MSGQ_OPEN_FAIL; Log_print1(Diags_INFO, "AspMsgMaster_init(): <-- status=%d", (IArg)status); return status; } Log_print0(Diags_INFO, "AspMsgMaster_init(): ASP Master messaging ready"); Log_info0("AspMsgMaster_init(): ASP Master messaging ready"); Log_print1(Diags_EXIT, "<-- AspMsgMaster_init(): %d", (IArg)status); return 0; } /************************************************************************************ * ASP message sending function. Refer to aspMsg_master.h for detailed description. ************************************************************************************/ Int AspMsgSend(UInt32 sndCmd, UInt32 ackCmd, char *sndMsgBuf, char *ackMsgBuf) { ASP_Msg* pAspMsg; /* Messaging */ Int status; // allocate message pAspMsg = (ASP_Msg *)MessageQ_alloc(hAspMsgMaster->heapId, hAspMsgMaster->msgSize); if (pAspMsg == NULL) { TRACE_TERSE0("MessageQ_alloc() failure."); return (ASP_MSG_ERR_QUEUE_ALLOC); } // set the return address in the message header and fill in message payload MessageQ_setReplyQueue(hAspMsgMaster->masterQue, (MessageQ_Msg)pAspMsg); pAspMsg->cmd = sndCmd; pAspMsg->procId = hAspMsgMaster->masterProcId; pAspMsg->messageId = hAspMsgMaster->messageId & ~(1<<31); pAspMsg->expectResp = TRUE; // copy the message provided by caller if(sndMsgBuf != NULL) { memcpy(pAspMsg->buf, sndMsgBuf, ASP_MSG_BUF_LEN*sizeof(char)); } // send the message TRACE_TERSE3("ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId); status = MessageQ_put(hAspMsgMaster->slaveQue, (MessageQ_Msg)pAspMsg); if (status != MessageQ_S_SUCCESS) { TRACE_TERSE0("MessageQ_put() failure."); MessageQ_free((MessageQ_Msg)pAspMsg); return (ASP_MSG_ERR_QUEUE_PUT); } // wait for complete message from slave status = MessageQ_get(hAspMsgMaster->masterQue, (MessageQ_Msg *)&pAspMsg, MessageQ_FOREVER); if (status != MessageQ_S_SUCCESS) { TRACE_TERSE0("MessageQ_get() failure."); MessageQ_free((MessageQ_Msg)pAspMsg); return (ASP_MSG_ERR_QUEUE_GET); } // check if returned message is valid if ((pAspMsg->procId != hAspMsgMaster->slaveProcId) || (pAspMsg->cmd != ackCmd) || (pAspMsg->messageId != (hAspMsgMaster->messageId | ((UInt32)1<<31)))) { TRACE_TERSE3("ERROR: ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId); MessageQ_free((MessageQ_Msg)pAspMsg); return(ASP_MSG_ERR_ACKNOWLEDGE); } hAspMsgMaster->messageId = (hAspMsgMaster->messageId + 1) & ~(1<<31); TRACE_TERSE3("ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId); // get the returned message if(ackMsgBuf != NULL) { memcpy(ackMsgBuf, pAspMsg->buf, ASP_MSG_BUF_LEN*sizeof(char)); } // free the message status = MessageQ_free((MessageQ_Msg)pAspMsg); if (status != MessageQ_S_SUCCESS) { TRACE_TERSE0("MessageQ_free() failure."); return (ASP_MSG_ERR_QUEUE_FREE); } // No error in messaging operation, even though there // may be error in returned (acknowledgement) message. return (ASP_MSG_NO_ERR); } /* AspMsgSend */