This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
/**
* @file mmw_lvds_stream.c
*
* @brief
* Implements LVDS stream functionality.
*
* \par
* NOTE:
* (C) Copyright 2021 Texas Instruments, Inc.
*
* 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 Files ********************************
**************************************************************************/
#include <stdint.h>
#include <string.h>
#include <stdio.h>
/* MMWSDK Include Files. */
#include <ti/common/sys_common.h>
#include <ti/utils/hsiheader/hsiheader.h>
/* PDK Include Files */
#include <kernel/dpl/DebugP.h>
#include <kernel/dpl/SemaphoreP.h>
#include <drivers/adcbuf.h>
#include <drivers/edma.h>
#include <drivers/cbuff.h>
#include <drivers/soc.h>
/* MMWAVE Demo Include Files */
#include "../mmw_res.h"
#include "mmw_dss.h"
#include "mmw_lvds_stream.h"
extern MmwDemo_DSS_MCB gMmwDssMCB;
/**
* @b Description
* @n
* This function initializes/configures the LVDS
* streaming EDMA resources.
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
void MmwDemo_LVDSStream_EDMAInit (void)
{
gMmwDssMCB.lvdsStream.swSessionEDMAChannelAllocatorIndex = 0;
/* Populate the LVDS Stream SW Session EDMA Channel Table: */
gMmwDssMCB.lvdsStream.swSessionEDMAChannelTable[0].chainChannelsId = MMW_LVDS_STREAM_SW_SESSION_EDMA_CH_0;
gMmwDssMCB.lvdsStream.swSessionEDMAChannelTable[0].shadowLinkChannelsId = MMW_LVDS_STREAM_SW_SESSION_EDMA_SHADOW_CH_0;
gMmwDssMCB.lvdsStream.swSessionEDMAChannelTable[1].chainChannelsId = MMW_LVDS_STREAM_SW_SESSION_EDMA_CH_1;
gMmwDssMCB.lvdsStream.swSessionEDMAChannelTable[1].shadowLinkChannelsId = MMW_LVDS_STREAM_SW_SESSION_EDMA_SHADOW_CH_1;
gMmwDssMCB.lvdsStream.swSessionEDMAChannelTable[2].chainChannelsId = MMW_LVDS_STREAM_SW_SESSION_EDMA_CH_2;
gMmwDssMCB.lvdsStream.swSessionEDMAChannelTable[2].shadowLinkChannelsId = MMW_LVDS_STREAM_SW_SESSION_EDMA_SHADOW_CH_2;
}
/**
* @b Description
* @n
* This is the LVDS streaming init function.
* It initializes the necessary modules
* that implement the streaming.
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
int32_t MmwDemo_LVDSStreamInit (void)
{
int32_t retVal = MINUS_ONE;
CBUFF_InitCfg initCfg;
int32_t errCode;
/*************************************************************************************
* Open the CBUFF Driver:
*************************************************************************************/
memset ((void *)&initCfg, 0, sizeof(CBUFF_InitCfg));
/* Populate the configuration: */
initCfg.enableECC = 0U;
initCfg.crcEnable = 1U;
/* Up to 1 SW session + 1 HW session can be configured for each frame. Therefore max session is 2. */
initCfg.maxSessions = 2U;
initCfg.enableDebugMode = false;
initCfg.interface = CBUFF_Interface_LVDS;
initCfg.outputDataFmt = CBUFF_OutputDataFmt_16bit;
initCfg.lvdsCfg.crcEnable = 0U;
initCfg.lvdsCfg.msbFirst = 1U;
/* Enable all lanes available on the platform*/
initCfg.lvdsCfg.lvdsLaneEnable = 0x3U;
initCfg.lvdsCfg.ddrClockMode = 1U;
initCfg.lvdsCfg.ddrClockModeMux = 1U;
#if 1
/* Configure HSI interface Clock */
HW_WR_REG32(CSL_MSS_TOPRCM_U_BASE + CSL_MSS_TOPRCM_HSI_CLK_SRC_SEL, 0x222);
HW_WR_REG32(CSL_MSS_TOPRCM_U_BASE + CSL_MSS_TOPRCM_HSI_DIV_VAL, 0x333);
/* Initialize the CBUFF Driver: */
gMmwDssMCB.lvdsStream.cbuffHandle = CBUFF_open(&initCfg, &errCode);
if (gMmwDssMCB.lvdsStream.cbuffHandle == NULL)
{
/* Error: Unable to initialize the CBUFF Driver */
test_print("Error: CBUFF_init failed with [Error=%d]\n", errCode);
goto exit;
}
#endif
/* Initialize the HSI Header Module: */
if (HSIHeader_init (&initCfg, &errCode) < 0)
{
/* Error: Unable to initialize the HSI Header Module */
test_print("Error: HSIHeader_init failed with [Error=%d]\n", errCode);
goto exit;
}
/* Populate EDMA resources */
MmwDemo_LVDSStream_EDMAInit();
/* Initialize semaphores */
SemaphoreP_constructBinary(&gMmwDssMCB.lvdsStream.hwFrameDoneSemHandle, 0);
SemaphoreP_constructBinary(&gMmwDssMCB.lvdsStream.swFrameDoneSemHandle, 0);
retVal = 0;
exit:
return retVal;
}
/**
* @b Description
* @n
* Function that allocates CBUFF-EDMA channel
*
* @param[in] ptrEDMAInfo
* Pointer to the EDMA Information
* @param[out] ptrEDMACfg
* Populated EDMA channel configuration
*
*/
static void MmwDemo_LVDSStream_EDMAAllocateCBUFFChannel
(
CBUFF_EDMAInfo* ptrEDMAInfo,
CBUFF_EDMAChannelCfg* ptrEDMACfg
)
{
if(ptrEDMAInfo->dmaNum == 0)
{
ptrEDMACfg->chainChannelsId = MMW_LVDS_STREAM_CBUFF_EDMA_CH_0;
ptrEDMACfg->shadowLinkChannelsId = MMW_LVDS_STREAM_CBUFF_EDMA_SHADOW_CH_0;
}
else if(ptrEDMAInfo->dmaNum == 1)
{
ptrEDMACfg->chainChannelsId = MMW_LVDS_STREAM_CBUFF_EDMA_CH_1;
ptrEDMACfg->shadowLinkChannelsId = MMW_LVDS_STREAM_CBUFF_EDMA_SHADOW_CH_1;
}
else
{
/* Max of 2 CBUFF sessions can be configured*/
MmwDemo_debugAssert (0);
}
}
/**
* @b Description
* @n
* This is the registered CBUFF EDMA channel allocation function
* which allocates EDMA channels for CBUFF SW Session
*
* @param[in] ptrEDMAInfo
* Pointer to the EDMA Information
* @param[out] ptrEDMACfg
* Populated EDMA channel configuration
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
static int32_t MmwDemo_LVDSStream_EDMAAllocateCBUFFSwChannel
(
CBUFF_EDMAInfo* ptrEDMAInfo,
CBUFF_EDMAChannelCfg* ptrEDMACfg
)
{
int32_t retVal = MINUS_ONE;
MmwDemo_LVDSStream_MCB_t *streamMCBPtr = &gMmwDssMCB.lvdsStream;
if(ptrEDMAInfo->isFirstEDMAChannel)
{
MmwDemo_LVDSStream_EDMAAllocateCBUFFChannel(ptrEDMAInfo,ptrEDMACfg);
retVal = 0;
}
else
{
/* Sanity Check: Are there sufficient EDMA channels? */
if (streamMCBPtr->swSessionEDMAChannelAllocatorIndex >= MMWDEMO_LVDS_STREAM_SW_SESSION_MAX_EDMA_CHANNEL)
{
/* Error: All the EDMA channels are allocated */
test_print ("Error: MmwDemo_LVDSStream_EDMAAllocateCBUFFChannel failed. SW channel index=%d\n",
streamMCBPtr->swSessionEDMAChannelAllocatorIndex);
goto exit;
}
/* Copy over the allocated EDMA configuration. */
memcpy ((void *)ptrEDMACfg,
(void*)&streamMCBPtr->swSessionEDMAChannelTable[streamMCBPtr->swSessionEDMAChannelAllocatorIndex],
sizeof(CBUFF_EDMAChannelCfg));
/* Increment the allocator index: */
streamMCBPtr->swSessionEDMAChannelAllocatorIndex++;
/* EDMA Channel allocated successfully */
retVal = 0;
}
exit:
return retVal;
}
/**
* @b Description
* @n
* This is the registered CBUFF EDMA channel free function which frees EDMA channels
* which had been allocated for use by a CBUFF SW Session
*
* @retval
* Not applicable
*/
static void MmwDemo_LVDSStream_EDMAFreeCBUFFSwChannel (CBUFF_EDMAChannelCfg* ptrEDMACfg)
{
uint8_t index;
MmwDemo_LVDSStream_MCB_t *streamMCBPtr = &gMmwDssMCB.lvdsStream;
if((ptrEDMACfg->chainChannelsId == MMW_LVDS_STREAM_CBUFF_EDMA_CH_0) ||
(ptrEDMACfg->chainChannelsId == MMW_LVDS_STREAM_CBUFF_EDMA_CH_1))
{
/*This is the CBUFF trigger channel. It is not part of the resource table so
nothing needs to be done*/
goto exit;
}
for (index = 0U; index < MMWDEMO_LVDS_STREAM_SW_SESSION_MAX_EDMA_CHANNEL; index++)
{
/* Do we have a match? */
if (memcmp ((void*)ptrEDMACfg,
(void*)&streamMCBPtr->swSessionEDMAChannelTable[index],
sizeof(CBUFF_EDMAChannelCfg)) == 0)
{
/* Yes: Decrement the SW Session index */
streamMCBPtr->swSessionEDMAChannelAllocatorIndex--;
goto exit;
}
}
/* Sanity Check: We should have had a match. An assertion is thrown to indicate that the EDMA channel
* being cleaned up does not belong to the table*/
MmwDemo_debugAssert (0);
exit:
return;
}
/**
* @b Description
* @n
* This function deletes the SW session and any HSI
* header associated with it.
*
* @retval
* Not applicable
*/
void MmwDemo_LVDSStreamDeleteSwSession (void)
{
int32_t errCode;
MmwDemo_LVDSStream_MCB_t* streamMcb = &gMmwDssMCB.lvdsStream;
/* Delete session*/
if (CBUFF_close (streamMcb->swSessionHandle, &errCode) < 0)
{
/* Error: Unable to delete the session. */
test_print ("Error: MmwDemo_LVDSStreamDeleteSwSession CBUFF_close failed. Error code %d\n", errCode);
MmwDemo_debugAssert(0);
return;
}
streamMcb->swSessionHandle = NULL;
/* Delete the HSI Header: */
if (HSIHeader_deleteHeader (&streamMcb->swSessionHSIHeader, &errCode) < 0)
{
/* Error: Unable to delete the HSI Header */
test_print ("Error: MmwDemo_LVDSStreamDeleteSwSession HSIHeader_deleteHeader failed. Error code %d\n", errCode);
MmwDemo_debugAssert(0);
return;
}
}
/**
* @b Description
* @n
* This is the registered callback function which is invoked after the
* frame done interrupt is received for the SW session.
*
* @param[in] sessionHandle
* Handle to the session
*
* @retval
* Not applicable
*/
static void MmwDemo_LVDSStream_SwTriggerFrameDone (CBUFF_SessionHandle sessionHandle)
{
int32_t errCode;
/* Increment stats*/
gMmwDssMCB.lvdsStream.swFrameDoneCount++;
if(sessionHandle != NULL)
{
if(CBUFF_deactivateSession (sessionHandle, &errCode) < 0)
{
/* Error: Unable to deactivate the session. */
DebugP_assert(0);
return;
}
/*If only one subframe has been configured (legacy frame) and
a HW session has been configured for that subframe, we need to
enable it here as for the legacy frame the HW is NOT reconfigured
every frame.
If more than one subframe is configured, the HW
session is reconfigured and activated every subframe
in the application code, not here.*/
#if 0
if((gMmwDssMCB.objDetCommonCfg.preStartCommonCfg.numSubFrames == 1) &&
(gMmwDssMCB.lvdsStream.hwSessionHandle != NULL))
{
if(CBUFF_activateSession (gMmwDssMCB.lvdsStream.hwSessionHandle, &errCode) < 0)
{
DebugP_assert(0);
}
}
#endif
}
else
{
DebugP_assert(0);
}
SemaphoreP_post(&gMmwDssMCB.lvdsStream.swFrameDoneSemHandle);
}
/**
* @b Description
* @n
* This is the LVDS sw streaming config function.
* It configures the sw session for the LVDS streaming.
*
* @param[in] numObjOut Number of detected objects to stream out
* @param[in] objOut Pointer to detected objects point cloud
* @param[in] objOutSideInfo Pointer to detected objects side information
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
int32_t MmwDemo_LVDSStreamSwConfig (uint32_t numObjOut,
DPIF_PointCloudCartesian *objOut,
DPIF_PointCloudSideInfo *objOutSideInfo)
{
CBUFF_SessionCfg sessionCfg;
MmwDemo_LVDSStream_MCB_t* streamMcb = &gMmwDssMCB.lvdsStream;
int32_t errCode;
int32_t retVal = MINUS_ONE;
uint32_t address = 0x5A000000U;
memset ((void*)&sessionCfg, 0, sizeof(CBUFF_SessionCfg));
/* Populate the configuration: */
sessionCfg.executionMode = CBUFF_SessionExecuteMode_SW;
sessionCfg.edmaHandle = gMmwDssMCB.dataPathObj.edmaHandle[0];
sessionCfg.allocateEDMAChannelFxn = MmwDemo_LVDSStream_EDMAAllocateCBUFFSwChannel;
sessionCfg.freeEDMAChannelFxn = MmwDemo_LVDSStream_EDMAFreeCBUFFSwChannel;
sessionCfg.frameDoneCallbackFxn = MmwDemo_LVDSStream_SwTriggerFrameDone;
sessionCfg.dataType = CBUFF_DataType_REAL;
gUserBuffHead[sizeof(gUserBuffHead)/2 - 2] = g_frameNum;
gUserBuffHead[sizeof(gUserBuffHead)/2 - 1] = g_chirpNum;
sessionCfg.u.swCfg.userBufferInfo[0].size = sizeof(gUserBuffHead)/2;
sessionCfg.u.swCfg.userBufferInfo[0].address = (uint32_t)&gUserBuffHead;
/* Note size and addresses have defaulted to 0 due to memset zero initialization above */
sessionCfg.u.swCfg.userBufferInfo[1].size = 4094;
sessionCfg.u.swCfg.userBufferInfo[1].address = address;
sessionCfg.u.swCfg.userBufferInfo[2].size = sizeof(gUserBufferEnd)/2;
sessionCfg.u.swCfg.userBufferInfo[2].address = (uint32_t)&gUserBufferEnd;
/* Create the HSI Header to be used for the SW Session: */
if (HSIHeader_createHeader (&sessionCfg, true, &(streamMcb->swSessionHSIHeader), &errCode) < 0)
{
/* Error: Unable to create the HSI Header; report the error */
test_print("Error: MmwDemo_LVDSStream_config unable to create HW HSI header with [Error=%d]\n", errCode);
goto exit;
}
/* Setup the header in the CBUFF session configuration: */
sessionCfg.header.size = HSIHeader_getHeaderSize(&streamMcb->swSessionHSIHeader);
sessionCfg.header.address = (uint32_t)&(streamMcb->swSessionHSIHeader);
/* Create the SW Session. */
streamMcb->swSessionHandle = CBUFF_createSession (gMmwDssMCB.lvdsStream.cbuffHandle, &sessionCfg, &errCode);
if (streamMcb->swSessionHandle == NULL)
{
/* Error: Unable to create the CBUFF SW session */
test_print("Error: MmwDemo_LVDSStream_config unable to create the CBUFF SW session with [Error=%d]\n", errCode);
goto exit;
}
/* Control comes here implies that the LVDS Stream has been configured successfully */
retVal = 0;
exit:
return retVal;
}
是mss侧在 MmwDemo_dataPathConfig中调用MmwDemo_DPM_ioctl_blocking这个发送消息DPC_OBJDET_IOCTL__STATIC_PRE_START_COMMON_CFG,dss侧一直无法收到,导致后面信号处理的流程没有办法继续下去,一直卡死。
然后我注释掉上述代码中的cbuff_open这一行,就正常运行了!!!!
demo默认mss应该也是不支持的,需要打开lvds_stream这个宏,并且修改才能编译通过,并且运行也是同样的问题吧???
您这边说的测试ok的用于2944的demo具体是指哪一个???
\ti\mmwave_mcuplus_sdk_04_02_00_03\ti\demo\awr294x\mmw
ti\mmwave_mcuplus_sdk_04_02_00_03\ti\demo\awr294x\mmw\profiles\tdm_awr2944\profile_LVDS.cfg

但是这个demo,没有lab0015的ccs上述工程文件,只能通过命令行编译成appimage烧录进取调试,不是很方便
我想把这个demo导入到ccs进入调试,该如何做???(能否详细一点)
你好,
没有ccs工程也是可以在ccs里调试的,请参考sdk user guide里下面章节的内容。
3.2.2. CCS development mode