Other Parts Discussed in Thread: SYSBIOS
Tool/software: Code Composer Studio
Hi.
I am currently trying to integrate the CAN driver code into the lab srr_16xx. In order to integrate it I am pasting the code from C:\ti\mmwave_sdk_01_02_00_05\packages\ti\drivers\can\test\common into
the SRR_MSS_initTask function in the mss_main.c file. The modified code is attached.
I managed to make it compile properly but when I try to debug it i get the following error:
"[Cortex_R4_0] Debug: Launched the Initialization Task
ti.sysbios.family.arm.v7r.vim.Hwi: line 195: E_alreadyDefined: Hwi already defined: intr# 98
xdc.runtime.Main: "src/ti_rtos/HwiP_tirtos.c", line 95: assertion failure
xdc.runtime.Error.raise: terminating execution "
Any clue on how to solve this? My intention is to send the information that is sent through UART also through CAN, but I am not entirely sure how to do so.
Ty
Jaume
/*
* @file mss_main.c
*
* @brief
* SRR TI Design executing on the MSS
*
* \par
* NOTE:
* (C) Copyright 2018 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 ********************************
**************************************************************************/
/* Standard Include Files. */
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
/* BIOS/XDC Include Files. */
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/IHeap.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Memory.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/heaps/HeapBuf.h>
#include <ti/sysbios/heaps/HeapMem.h>
#include <ti/sysbios/knl/Event.h>
#include <ti/sysbios/family/arm/v7a/Pmu.h>
#include <ti/sysbios/family/arm/v7r/vim/Hwi.h>
/* mmWave SDK Include Files: */
#include <ti/common/sys_common.h>
#include <ti/drivers/soc/soc.h>
#include <ti/drivers/can/can.h>
#include <ti/drivers/esm/esm.h>
#include <ti/drivers/crc/crc.h>
#include <ti/drivers/uart/UART.h>
#include <ti/drivers/gpio/gpio.h>
#include <ti/drivers/mailbox/mailbox.h>
#include <ti/drivers/pinmux/pinmux.h>
#include <ti/drivers/osal/DebugP.h>
#include <ti/control/mmwavelink/mmwavelink.h>
#include <ti/control/mmwave/mmwave.h>
#include <ti/control/mmwavelink/include/rl_driver.h>
#include <ti/utils/testlogger/logger.h>
#include <ti/drivers/osal/HwiP.h>
/* Application Include Files: */
#include "mss_srr.h"
#include <common/srr_config_consts.h>
#include "common/mmw_messages.h"
#include <ti/utils/cli/cli.h>
#include <ti/drivers/cbuff/cbuff.h>
/**************************************************************************
*************************** Global Definitions ***************************
**************************************************************************/
/**
* @brief
* Initialize the MCPI Log Message Buffer
*/
MCPI_LOGBUF_INIT(9216);
/** \brief Number of messages sent */
#define DCAN_APP_TEST_INTERNAL_LOOPBACK 1
#define DCAN_APP_TEST_EXTERNAL_LOOPBACK 2
#define DCAN_APP_TEST_PARITY 3
#define DCAN_APP_TEST_EXTERNAL_DATA 4
/** \brief Number of messages sent */
#define DCAN_APP_TEST_MESSAGE_COUNT 100
/** \brief DCAN input clock - 20MHz */
#define DCAN_APP_INPUT_CLK (20000000U)
/** \brief DCAN output bit rate - 1MHz */
#define DCAN_APP_BIT_RATE (1000000U)
/** \brief DCAN Propagation Delay - 700ns */
#define DCAN_APP_PROP_DELAY (700U)
/** \brief DCAN Sampling Point - 70% */
#define DCAN_APP_SAMP_PT (70U)
/** \brief DCAN TX message object used */
#define DCAN_TX_MSG_OBJ (0x1U)
/** \brief DCAN RX message object used */
#define DCAN_RX_MSG_OBJ (0x2U)
/** \brief DCAN Message Object used for PARITY Test */
#define DCAN_NUM_MSG_OBJ (0x1)
#define DCAN_MSG_OBJ_1 (0x4)
#define DCAN_MSG_OBJ_2 (0x6)
/** \brief Message Object Size*/
#define DCAN_MSG_OBJ_SIZE (0x20U)
/** \brief DCAN Message Object RAM Address */
#if (defined(SOC_XWR14XX))
#define DCAN_MSG_OBJ_RAM_ADDR_1 ((SOC_XWR14XX_MSS_DCAN_MEM_BASE_ADDRESS) + \
(DCAN_MSG_OBJ_1 * DCAN_MSG_OBJ_SIZE))
#define DCAN_MSG_OBJ_RAM_ADDR_2 ((SOC_XWR14XX_MSS_DCAN_MEM_BASE_ADDRESS) + \
(DCAN_MSG_OBJ_2 * DCAN_MSG_OBJ_SIZE))
#else
#define DCAN_MSG_OBJ_RAM_ADDR_1 ((SOC_XWR16XX_MSS_DCAN_MEM_BASE_ADDRESS) + \
(DCAN_MSG_OBJ_1 * DCAN_MSG_OBJ_SIZE))
#define DCAN_MSG_OBJ_RAM_ADDR_2 ((SOC_XWR16XX_MSS_DCAN_MEM_BASE_ADDRESS) + \
(DCAN_MSG_OBJ_2 * DCAN_MSG_OBJ_SIZE))
#endif
/* Global Variables */
volatile uint32_t testSelection = 0;
volatile uint32_t gTxDoneFlag = 0, gRxDoneFlag = 0, gParityErrFlag = 0;
uint32_t iterationCount = 0U;
volatile uint32_t gTxPkts = 0, gRxPkts = 0, gErrStatusInt = 0;
CAN_DCANCfgParams appDcanCfgParams;
CAN_DCANMsgObjCfgParams appDcanTxCfgParams;
CAN_DCANMsgObjCfgParams appDcanRxCfgParams;
CAN_DCANBitTimeParams appDcanBitTimeParams;
CAN_DCANData appDcanTxData;
CAN_DCANData appDcanRxData;
uint32_t dataLength = 0U;
uint32_t msgLstErrCnt = 0U;
uint32_t dataMissMatchErrCnt = 0U;
uint32_t rxTicks[DCAN_APP_TEST_MESSAGE_COUNT];
uint32_t txTicks[DCAN_APP_TEST_MESSAGE_COUNT];
uint32_t minRxTicks;
uint32_t maxRxTicks;
uint32_t minTxTicks;
uint32_t maxTxTicks;
uint32_t totalTxTicks;
uint32_t totalRxTicks;
uint32_t gDisplayStats = 0;
/**
* @b Description
* @n
* This function starts the PMU counter.
*
* @param[in] counter
* Counter id used for benchmarking
*
* @retval
* Not Applicable.
*/
void Test_benchmarkStart(uint32_t counter)
{
/* Initialize counter to count cycles */
Pmu_configureCounter(counter, 0x11, FALSE);
/* Reset PMU counter */
Pmu_resetCount(counter);
/* Start PMU counter */
Pmu_startCounter(counter);
}
/**
* @b Description
* @n
* This function stops a PMU counter and returns the current
* counter value.
*
* @param[in] counter
* Counter id used for benchmarking
*
* @retval
* Current PMU counter value.
*/
uint32_t Test_benchmarkStop(uint32_t counter)
{
/* Stop PMU counter */
Pmu_stopCounter(counter);
/* Read PMU counter */
return (Pmu_getCount(counter));
}
/**
* @b Description
* @n
* Application implemented callback function to handle error and status interrupts.
*
* @param[in] handle
* Handle to the CAN Driver
* @param[in] errStatusResp
* Response structure containing the Error and status information
*
* @retval
* Not Applicable.
*/
static void DCANAppErrStatusCallback(CAN_Handle handle, CAN_ErrStatusResp* errStatusResp)
{
gErrStatusInt++;
if (errStatusResp->parityError == 1)
{
gParityErrFlag = 1;
}
return;
}
/**
* @b Description
* @n
* Application implemented callback function to handle Tx complete and receive interrupts.
*
* @param[in] handle
* Handle to the message object
* @param[in] msgObjectNum
* Message object number
* @param[in] direction
* Direction of the object number
*
* @retval
* Not Applicable.
*/
static void DCANAppCallback(CAN_MsgObjHandle handle, uint32_t msgObjectNum, CAN_Direction direction)
{
int32_t errCode, retVal;
if (direction == CAN_Direction_TX)
{
if (msgObjectNum != DCAN_TX_MSG_OBJ)
{
System_printf ("Error: Tx callback received for incorrect Message Object %d\n", msgObjectNum);
return;
}
else
{
gTxPkts++;
gTxDoneFlag = 1;
return;
}
}
if (direction == CAN_Direction_RX)
{
if (msgObjectNum != DCAN_RX_MSG_OBJ)
{
System_printf ("Error: Rx callback received for incorrect Message Object %d\n", msgObjectNum);
return;
}
else
{
/* Reset the receive buffer */
memset(&appDcanRxData, 0, sizeof (appDcanRxData));
dataLength = 0;
if ((testSelection != DCAN_APP_TEST_EXTERNAL_DATA) && (gRxPkts < DCAN_APP_TEST_MESSAGE_COUNT))
{
/* Reset the counter: */
Test_benchmarkStart(0);
}
retVal = CAN_getData (handle, &appDcanRxData, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN receive data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
return;
}
if ((testSelection != DCAN_APP_TEST_EXTERNAL_DATA) && (gRxPkts < DCAN_APP_TEST_MESSAGE_COUNT))
{
/* Stop the counter: */
rxTicks[gRxPkts] = Test_benchmarkStop(0);
/* Update the receive statistics: */
minRxTicks = (minRxTicks < rxTicks[gRxPkts]) ? minRxTicks : rxTicks[gRxPkts];
maxRxTicks = (maxRxTicks > rxTicks[gRxPkts]) ? maxRxTicks : rxTicks[gRxPkts];
totalRxTicks = totalRxTicks + rxTicks[gRxPkts];
}
/* Check if sent data is lost or not */
if (appDcanRxData.msgLostFlag == 1)
{
msgLstErrCnt++;
}
/* Validate the data */
if ((testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK) || (testSelection == DCAN_APP_TEST_EXTERNAL_LOOPBACK))
{
/* Check if sent data has been received */
if (appDcanRxData.dataLength == appDcanTxData.dataLength)
{
while (dataLength < appDcanRxData.dataLength)
{
if (appDcanRxData.msgData[dataLength] != appDcanTxData.msgData[dataLength])
{
dataMissMatchErrCnt++;
System_printf ("Error: CAN receive data mismatch for iteration %d at byte %d\n", iterationCount, dataLength);
}
dataLength++;
}
}
}
gRxPkts++;
gRxDoneFlag = 1;
return;
}
}
}
/**
* \brief This function takes I/P Clk frequency, required bit-rate, reference
* sampling point, propagation delayon the CAN bus and calculates the
* value to be programmed for DCAN BTR register.
* This API doesn't do the actual programming. This is
* intended to be used as a utility function. And the application
* should call the #DCANSetBitTime function to do the actual
* programming.
*
* \param clkFreq I/P clock frequency to DCAN controller in terms of MHz
* \param bitRate Required bit-rate on the CAN bus in KHz
* \param refSamplePnt Reference Sampling point in terms of %
* \param propDelay Required Propagation delay in terms of ns
* \param bitTimeParams Pointer to params where the calculated register
* fields are populated
*
* \return Returns the error status information as STW_SOK for success and
* STW_EFAIL when no valid baudrate calculation possible for the
* configured baudrate and propagation delay
*/
int32_t DCANAppCalcBitTimeParams(uint32_t clkFreq,
uint32_t bitRate,
uint32_t refSamplePnt,
uint32_t propDelay,
CAN_DCANBitTimeParams* bitTimeParams)
{
Double tBitRef = 1000 * 1000 / bitRate;
Double newBaud = 0, newNProp = 0, newNSeg = 0, newSjw = 0, newP = 0;
Double nQRef, nProp, fCan, nQ, nSeg, baud, sp, p, newSp = 0;
float tQ;
for (p = 1; p <= 1024; p++)
{
tQ = ((p / clkFreq) * 1000.0);
nQRef = tBitRef / tQ;
if ((nQRef >= 8) && (nQRef <= 25))
{
nProp = ceil(propDelay / tQ);
fCan = clkFreq / p;
nQ = fCan / bitRate * 1000;
nSeg = ceil((nQ - nProp - 1) / 2);
if ((nProp <= 8) && (nProp > 0) && (nSeg <= 8) && (nSeg > 0))
{
baud = fCan / (1 + nProp + 2 * nSeg) * 1000;
sp = (1 + nProp + nSeg) / (1 + nProp + nSeg + nSeg) * 100;
if ((abs(baud - bitRate)) < (abs(newBaud - bitRate)))
{
newBaud = baud;
newNProp = nProp;
newNSeg = nSeg;
newSjw = (nSeg < 4) ? nSeg : 4;
newP = p - 1;
newSp = sp;
}
else if ((abs(baud - bitRate)) == (abs(newBaud - bitRate)))
{
if ((abs(sp - refSamplePnt)) < (abs(newSp - refSamplePnt)))
{
newBaud = baud;
newNProp = nProp;
newNSeg = nSeg;
newSjw = (nSeg < 4) ? nSeg : 4;
newP = p - 1;
newSp = sp;
}
}
}
}
}
if ((newBaud == 0) || (newBaud > 1000))
{
return -1;
}
bitTimeParams->baudRatePrescaler = (((uint32_t) newP) & 0x3F);
bitTimeParams->baudRatePrescalerExt =
((((uint32_t) newP) & 0x3C0) ? (((uint32_t) newP) & 0x3C0) >> 6 : 0);
bitTimeParams->syncJumpWidth = ((uint32_t) newSjw) - 1;
/* propSeg = newNProp, phaseSeg = newNSeg, samplePoint = newSp
* nominalBitTime = (1 + newNProp + 2 * newNSeg), nominalBitRate = newBaud
* brpFreq = clkFreq / (brp + 1), brpeFreq = clkFreq / (newP + 1)
* brp = bitTimeParams->baudRatePrescaler;
*/
bitTimeParams->timeSegment1 = newNProp + newNSeg - 1;
bitTimeParams->timeSegment2 = newNSeg - 1;
return 0;
}
/**
* @b Description
* @n
* Platform specific intializations.
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
static int32_t PlatformInit(void)
{
int32_t errCode;
SOC_Handle socHandle;
SOC_Cfg socCfg;
/* Initialize the SOC confiugration: */
memset ((void *)&socCfg, 0, sizeof(SOC_Cfg));
/* Populate the SOC configuration: */
socCfg.clockCfg = SOC_SysClock_INIT;
/* Initialize the SOC Module: This is done as soon as the application is started
* to ensure that the MPU is correctly configured. */
socHandle = SOC_init (&socCfg, &errCode);
if (socHandle == NULL)
{
System_printf ("Error: SOC Module Initialization failed [Error code %d]\n", errCode);
return -1;
}
#if (defined(SOC_XWR14XX))
/* Setup the PINMUX to bring out the XWR14xx CAN pins */
Pinmux_Set_OverrideCtrl(SOC_XWR14XX_PINP5_PADAE, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR14XX_PINP5_PADAE, SOC_XWR14XX_PINP5_PADAE_CAN_TX);
Pinmux_Set_OverrideCtrl(SOC_XWR14XX_PINR8_PADAD, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR14XX_PINR8_PADAD, SOC_XWR14XX_PINR8_PADAD_CAN_RX);
#else
/* Setup the PINMUX to bring out the XWR16xx CAN pins */
Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINC13_PADAG, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINC13_PADAG, SOC_XWR16XX_PINC13_PADAG_CAN_TX);
Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINE13_PADAF, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINE13_PADAF, SOC_XWR16XX_PINE13_PADAF_CAN_RX);
#endif
/* Configure the divide value for DCAN source clock */
SOC_setPeripheralClock(socHandle, SOC_MODULE_DCAN, SOC_CLKSOURCE_VCLK, 9U, &errCode);
/* Initialize peripheral memory */
SOC_initPeripheralRam(socHandle, SOC_MODULE_DCAN, &errCode);
return 0;
}
static void DCANAppInitParams(CAN_DCANCfgParams* dcanCfgParams,
CAN_DCANMsgObjCfgParams* dcanTxCfgParams,
CAN_DCANMsgObjCfgParams* dcanRxCfgParams,
CAN_DCANData* dcanTxData)
{
/*Intialize DCAN Config Params*/
if (testSelection == DCAN_APP_TEST_PARITY)
{
dcanCfgParams->parityEnable = 1;
dcanCfgParams->intrLine0Enable = 1;
dcanCfgParams->intrLine1Enable = 0;
dcanCfgParams->testModeEnable = 0;
dcanCfgParams->eccModeEnable = 1;
dcanCfgParams->eccDiagModeEnable = 0;
dcanCfgParams->sbeEventEnable = 1;
dcanCfgParams->stsChangeIntrEnable = 0;
}
else if (testSelection == DCAN_APP_TEST_EXTERNAL_DATA)
{
dcanCfgParams->parityEnable = 0;
dcanCfgParams->intrLine0Enable = 1;
dcanCfgParams->intrLine1Enable = 1;
dcanCfgParams->testModeEnable = 0;
dcanCfgParams->eccModeEnable = 0;
dcanCfgParams->stsChangeIntrEnable = 0;
}
else
{
dcanCfgParams->parityEnable = 0;
dcanCfgParams->intrLine0Enable = 1;
dcanCfgParams->intrLine1Enable = 1;
dcanCfgParams->eccModeEnable = 0;
dcanCfgParams->testModeEnable = 1;
if (testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK)
{
dcanCfgParams->testMode = CAN_DCANTestMode_LPBACK;
dcanCfgParams->stsChangeIntrEnable = 0;
}
else
{
dcanCfgParams->testMode = CAN_DCANTestMode_EXT_LPBACK;
dcanCfgParams->stsChangeIntrEnable = 1;
}
}
dcanCfgParams->autoRetransmitDisable = 1;
dcanCfgParams->autoBusOnEnable = 0;
dcanCfgParams->errIntrEnable = 1;
dcanCfgParams->autoBusOnTimerVal = 0;
dcanCfgParams->if1DmaEnable = 0;
dcanCfgParams->if2DmaEnable = 0;
dcanCfgParams->if3DmaEnable = 0;
dcanCfgParams->ramAccessEnable = 0;
dcanCfgParams->appCallBack = DCANAppErrStatusCallback;
/*Intialize DCAN tx Config Params*/
dcanTxCfgParams->xIdFlagMask = 0x1;
dcanTxCfgParams->dirMask = 0x1;
dcanTxCfgParams->msgIdentifierMask = 0x1FFFFFFF;
dcanTxCfgParams->msgValid = 1;
dcanTxCfgParams->xIdFlag = CAN_DCANXidType_11_BIT;
dcanTxCfgParams->direction = CAN_Direction_TX;
dcanTxCfgParams->msgIdentifier = 0xC1;
dcanTxCfgParams->uMaskUsed = 1;
if (testSelection == DCAN_APP_TEST_PARITY)
dcanTxCfgParams->intEnable = 0;
else
dcanTxCfgParams->intEnable = 1;
dcanTxCfgParams->remoteEnable = 0;
dcanTxCfgParams->fifoEOBFlag = 1;
dcanTxCfgParams->appCallBack = DCANAppCallback;
/*Intialize DCAN Rx Config Params*/
dcanRxCfgParams->xIdFlagMask = 0x1;
dcanRxCfgParams->msgIdentifierMask = 0x1FFFFFFF;
dcanRxCfgParams->dirMask = 0x1;
dcanRxCfgParams->msgValid = 1;
dcanRxCfgParams->xIdFlag = CAN_DCANXidType_11_BIT;
dcanRxCfgParams->direction = CAN_Direction_RX;
dcanRxCfgParams->msgIdentifier = 0xC1;
dcanRxCfgParams->uMaskUsed = 1;
if (testSelection == DCAN_APP_TEST_PARITY)
dcanRxCfgParams->intEnable = 0;
else
dcanRxCfgParams->intEnable = 1;
dcanRxCfgParams->remoteEnable = 0;
dcanRxCfgParams->fifoEOBFlag = 1;
dcanRxCfgParams->appCallBack = DCANAppCallback;
/*Intialize DCAN Tx transfer Params*/
dcanTxData->dataLength = DCAN_MAX_MSG_LENGTH;
dcanTxData->msgData[0] = 0xA5;
dcanTxData->msgData[1] = 0x5A;
dcanTxData->msgData[2] = 0xFF;
dcanTxData->msgData[3] = 0xFF;
dcanTxData->msgData[4] = 0xC3;
dcanTxData->msgData[5] = 0x3C;
dcanTxData->msgData[6] = 0xB4;
dcanTxData->msgData[7] = 0x4B;
}
static int32_t dcanParityTest(void)
{
CAN_Handle canHandle;
CAN_MsgObjHandle txMsgObjHandle;
CAN_MsgObjHandle rxMsgObjHandle;
int32_t retVal = 0;
int32_t errCode = 0;
CAN_OptionTLV optionTLV;
uint8_t value;
CAN_DCANEccErrSts eccErrSts;
int32_t* ptrMsgObjMem;
gTxDoneFlag = 0;
/* Initialize the DCAN parameters that need to be specified by the application */
DCANAppInitParams(&appDcanCfgParams,
&appDcanTxCfgParams,
&appDcanRxCfgParams,
&appDcanTxData);
/* Initialize the CAN driver */
canHandle = CAN_init(&appDcanCfgParams, &errCode);
if (canHandle == NULL)
{
System_printf ("Error: CAN Module Initialization failed [Error code %d]\n", errCode);
return -1;
}
/* Set the desired bit rate based on input clock */
retVal = DCANAppCalcBitTimeParams(DCAN_APP_INPUT_CLK / 1000000,
DCAN_APP_BIT_RATE / 1000,
DCAN_APP_SAMP_PT,
DCAN_APP_PROP_DELAY,
&appDcanBitTimeParams);
if (retVal < 0)
{
System_printf ("Error: CAN Module bit time parameters are incorrect \n");
return -1;
}
/* Configure the CAN driver */
retVal = CAN_configBitTime (canHandle, &appDcanBitTimeParams, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN Module configure bit time failed [Error code %d]\n", errCode);
return -1;
}
/* Setup the transmit message object */
txMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_MSG_OBJ_1, &appDcanTxCfgParams, &errCode);
if (txMsgObjHandle == NULL)
{
System_printf ("Error: CAN create Tx message object failed [Error code %d]\n", errCode);
return -1;
}
/* Setup the receive message object */
rxMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_MSG_OBJ_2, &appDcanRxCfgParams, &errCode);
if (rxMsgObjHandle == NULL)
{
System_printf ("Error: CAN create Rx message object failed [Error code %d]\n", errCode);
return -1;
}
/* Send data over Tx message object */
retVal = CAN_transmitData (txMsgObjHandle, &appDcanTxData, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN transmit data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
return -1;
}
/* Disable parity to corrupt the RAM */
optionTLV.type = CAN_Option_DCAN_PARITY;
optionTLV.length = sizeof(uint8_t);
value = 0;
optionTLV.value = (void*) &value;
retVal = CAN_setOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN set option disable PARITY failed [Error code %d]\n", errCode);
return -1;
}
/* Enable ECC Diagnostics */
optionTLV.type = CAN_Option_DCAN_ECC_DIAG;
optionTLV.length = sizeof(uint8_t);
value = 1;
optionTLV.value = (void*) &value;
retVal = CAN_setOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN set option enable ECC DIAG failed [Error code %d]\n", errCode);
return -1;
}
ptrMsgObjMem = (int32_t *) (DCAN_MSG_OBJ_RAM_ADDR_1);
/* Corrupting the data in Message RAM in RDA Mode :
* as 0xC343B44A instead of 0xC343B44B which introduces
* single bit error for ECC test / Parity Error for Parity test.
*/
*ptrMsgObjMem = (*ptrMsgObjMem & 0xFFFFFFFE);
ptrMsgObjMem = (int32_t *) (DCAN_MSG_OBJ_RAM_ADDR_2);
/* Corrupting the data in Message RAM in RDA Mode :
* as 0xC343B448 instead of 0xC343B44B which introduces single bit error.
*/
*ptrMsgObjMem = (*ptrMsgObjMem & 0xFFFFFFFC);
/* Enable parity to corrupt the RAM */
optionTLV.type = CAN_Option_DCAN_PARITY;
optionTLV.length = sizeof(uint8_t);
value = 1;
optionTLV.value = (void*) &value;
retVal = CAN_setOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN set option enable PARITY failed [Error code %d]\n", errCode);
return -1;
}
/* Reset the receive buffer */
memset(&appDcanRxData, 0, sizeof (appDcanRxData));
dataLength = 0;
retVal = CAN_getData (txMsgObjHandle, &appDcanRxData, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN receive data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
return -1;
}
/* Wait for the parity error interrupt */
while (gParityErrFlag == 0);
/* Get the ECC error status */
optionTLV.type = CAN_Option_DCAN_ECC_ERROR_STATUS;
optionTLV.length = sizeof(CAN_DCANEccErrSts);
optionTLV.value = (void*) &eccErrSts;
retVal = CAN_getOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN get option ECC status failed [Error code %d]\n", errCode);
return -1;
}
if ((eccErrSts.singleBitErr != 1) || (eccErrSts.doubleBitErr != 1) ||
(eccErrSts.messageNum != DCAN_MSG_OBJ_1))
{
System_printf ("Error: ECC error status check failed. Single bit error %d Double bit error %d Message Number %d\n",
eccErrSts.singleBitErr, eccErrSts.doubleBitErr, eccErrSts.messageNum);
return -1;
}
else
{
System_printf ("Debug: ECC error status check passed. Single bit error %d Double bit error %d Message Number %d\n",
eccErrSts.singleBitErr, eccErrSts.doubleBitErr, eccErrSts.messageNum);
}
/* Clear the ECC error status */
optionTLV.type = CAN_Option_DCAN_CLEAR_ECC_ERROR_STATUS;
optionTLV.length = sizeof(uint8_t);
value = 1;
optionTLV.value = (void*) &value;
retVal = CAN_setOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN set option Clear the ECC error status failed [Error code %d]\n", errCode);
return -1;
}
/* Get the ECC Diagnostics error status */
optionTLV.type = CAN_Option_DCAN_ECC_DIAG_ERROR_STATUS;
optionTLV.length = sizeof(CAN_DCANEccErrSts);
optionTLV.value = (void*) &eccErrSts;
retVal = CAN_getOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN get option ECC Diagnostics status failed [Error code %d]\n", errCode);
return -1;
}
if ((eccErrSts.singleBitErr != 1) || (eccErrSts.doubleBitErr != 1) ||
(eccErrSts.messageNum != DCAN_MSG_OBJ_1))
{
System_printf ("Error: ECC Diag error status check failed Single bit error %d Double bit error %d\n",
eccErrSts.singleBitErr, eccErrSts.doubleBitErr);
return -1;
}
else
{
System_printf ("Debug: ECC Diag error status check passed Single bit error %d Double bit error %d\n",
eccErrSts.singleBitErr, eccErrSts.doubleBitErr);
}
/* Clear the ECC Diagnostics error status */
optionTLV.type = CAN_Option_DCAN_CLEAR_ECC_DIAG_ERROR_STATUS;
optionTLV.length = sizeof(uint8_t);
value = 1;
optionTLV.value = (void*) &value;
retVal = CAN_setOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN set option Clear the ECC Diagnostics error status failed [Error code %d]\n", errCode);
return -1;
}
/* Disable ECC Diagnostics */
optionTLV.type = CAN_Option_DCAN_ECC_DIAG;
optionTLV.length = sizeof(uint8_t);
value = 0;
optionTLV.value = (void*) &value;
retVal = CAN_setOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN set option disable ECC DIAG failed [Error code %d]\n", errCode);
return -1;
}
retVal = CAN_deinit(canHandle, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN deinit failed [Error code %d]\n", errCode);
return -1;
}
return 0;
}
static int32_t dcanLoopbackTest()
{
CAN_Handle canHandle;
CAN_MsgObjHandle txMsgObjHandle;
CAN_MsgObjHandle rxMsgObjHandle;
int32_t retVal = 0;
int32_t errCode = 0;
CAN_OptionTLV optionTLV;
uint8_t value;
CAN_DCANMsgObjectStats msgObjStats;
gTxDoneFlag = 0;
/* Initialize the DCAN parameters that need to be specified by the application */
DCANAppInitParams(&appDcanCfgParams,
&appDcanTxCfgParams,
&appDcanRxCfgParams,
&appDcanTxData);
/* Initialize the CAN driver */
canHandle = CAN_init(&appDcanCfgParams, &errCode);
if (canHandle == NULL)
{
System_printf ("Error: CAN Module Initialization failed [Error code %d]\n", errCode);
return -1;
}
/* Set the desired bit rate based on input clock */
retVal = DCANAppCalcBitTimeParams(DCAN_APP_INPUT_CLK / 1000000,
DCAN_APP_BIT_RATE / 1000,
DCAN_APP_SAMP_PT,
DCAN_APP_PROP_DELAY,
&appDcanBitTimeParams);
if (retVal < 0)
{
System_printf ("Error: CAN Module bit time parameters are incorrect \n");
return -1;
}
/* Configure the CAN driver */
retVal = CAN_configBitTime (canHandle, &appDcanBitTimeParams, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN Module configure bit time failed [Error code %d]\n", errCode);
return -1;
}
/* Setup the transmit message object */
txMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_TX_MSG_OBJ, &appDcanTxCfgParams, &errCode);
if (txMsgObjHandle == NULL)
{
System_printf ("Error: CAN create Tx message object failed [Error code %d]\n", errCode);
return -1;
}
/* Setup the receive message object */
rxMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_RX_MSG_OBJ, &appDcanRxCfgParams, &errCode);
if (rxMsgObjHandle == NULL)
{
System_printf ("Error: CAN create Rx message object failed [Error code %d]\n", errCode);
return -1;
}
/* Initialize the measurement counters */
minRxTicks = 0xFFFFFFFFU;
maxRxTicks = 0U;
minTxTicks = 0xFFFFFFFFU;
maxTxTicks = 0U;
totalTxTicks = 0U;
totalRxTicks = 0U;
while (iterationCount != DCAN_APP_TEST_MESSAGE_COUNT)
{
/* Reset the counter: */
Test_benchmarkStart(0);
/* Send data over Tx message object */
retVal = CAN_transmitData (txMsgObjHandle, &appDcanTxData, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN transmit data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
return -1;
}
/* Stop the counter: */
txTicks[iterationCount] = Test_benchmarkStop(0);
/* Update the transmit statistics: */
minTxTicks = (minTxTicks < txTicks[iterationCount]) ? minTxTicks : txTicks[iterationCount];
maxTxTicks = (maxTxTicks > txTicks[iterationCount]) ? maxTxTicks : txTicks[iterationCount];
totalTxTicks = totalTxTicks + txTicks[iterationCount];
while (gTxDoneFlag == 0);
gTxDoneFlag = 0;
while (gRxDoneFlag == 0);
gRxDoneFlag = 0;
iterationCount++;
}
optionTLV.type = CAN_Option_DCAN_POWER_DOWN;
optionTLV.length = sizeof(uint8_t);
value = 1;
optionTLV.value = (void*) &value;
retVal = CAN_setOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN set option SLEEP failed [Error code %d]\n", errCode);
return -1;
}
optionTLV.type = CAN_Option_DCAN_POWER_DOWN;
optionTLV.length = sizeof(uint8_t);
value = 0;
optionTLV.value = (void*) &value;
retVal = CAN_setOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN set option WAKEUP failed [Error code %d]\n", errCode);
return -1;
}
System_printf("Debug: Number of iterations : %d\n", iterationCount);
System_printf("Debug: Number of messages transmitted : %d\n", gTxPkts);
System_printf("Debug: Number of messages received : %d\n", gRxPkts);
System_printf("Debug: Number of messages lost : %d\n", msgLstErrCnt);
System_printf("Debug: Number of data mismatch : %d\n", dataMissMatchErrCnt);
System_printf("Debug: Error Status Interrupt : %d\n", gErrStatusInt);
System_printf("\n\n");
msgObjStats.handle = txMsgObjHandle;
optionTLV.type = CAN_Option_DCAN_MSG_OBJECT_STATS;
optionTLV.length = sizeof(CAN_DCANMsgObjectStats);
optionTLV.value = (void*) &msgObjStats;
retVal = CAN_getOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN get stats failed [Error code %d]\n", errCode);
return -1;
}
System_printf("Debug: Message object number : %d\n", msgObjStats.msgObjectNum);
System_printf("Debug: Direction : %s\n", (msgObjStats.direction == 0) ? "Receive" : "Transmit");
System_printf("Debug: Number of interrupts received : %d\n", msgObjStats.interruptsRxed);
System_printf("Debug: Number of messages processed : %d\n", msgObjStats.messageProcessed);
System_printf("\n\n");
msgObjStats.handle = rxMsgObjHandle;
retVal = CAN_getOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN get stats failed [Error code %d]\n", errCode);
return -1;
}
System_printf("Debug: Message object number : %d\n", msgObjStats.msgObjectNum);
System_printf("Debug: Direction : %s\n", (msgObjStats.direction == 0) ? "Receive" : "Transmit");
System_printf("Debug: Number of interrupts received : %d\n", msgObjStats.interruptsRxed);
System_printf("Debug: Number of messages processed : %d\n", msgObjStats.messageProcessed);
System_printf("Debug: Receive & Transmit Measurements\n");
System_printf("Debug: Rx Min:%d Max: %d Average:%d ticks\n", minRxTicks, maxRxTicks, totalRxTicks/gTxPkts);
System_printf("Debug: Tx Min:%d Max: %d Average:%d ticks\n", minTxTicks, maxTxTicks, totalTxTicks/gRxPkts);
System_printf("\n\n");
retVal = CAN_deleteMsgObject(txMsgObjHandle, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN delete Tx message object failed [Error code %d]\n", errCode);
return -1;
}
retVal = CAN_deleteMsgObject(rxMsgObjHandle, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN delete Rx message object failed [Error code %d]\n", errCode);
return -1;
}
retVal = CAN_deinit(canHandle, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN deinit failed [Error code %d]\n", errCode);
return -1;
}
if ((msgLstErrCnt == 0) && (dataMissMatchErrCnt == 0))
{
if (testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK)
{
System_printf("Debug: Internal loopback testing for %d iterations Passed\n", iterationCount);
}
else
{
System_printf("Debug: External loopback testing for %d iterations Passed\n", iterationCount);
}
}
else
{
if (testSelection == DCAN_APP_TEST_INTERNAL_LOOPBACK)
{
System_printf("Debug: Internal loopback testing for %d iterations Failed\n", iterationCount);
retVal = -1;
}
else
{
System_printf("Debug: External loopback testing for %d iterations Failed\n", iterationCount);
retVal = -1;
}
}
return retVal;
}
static int32_t dcanTransmitTest()
{
CAN_Handle canHandle;
CAN_MsgObjHandle txMsgObjHandle;
CAN_MsgObjHandle rxMsgObjHandle;
int32_t retVal = 0;
int32_t errCode = 0;
CAN_DCANMsgObjectStats msgObjStats;
CAN_OptionTLV optionTLV;
CAN_DCANErrorCounter errCounter;
/* Initialize the DCAN parameters that need to be specified by the application */
DCANAppInitParams(&appDcanCfgParams,
&appDcanTxCfgParams,
&appDcanRxCfgParams,
&appDcanTxData);
/* Initialize the CAN driver */
canHandle = CAN_init(&appDcanCfgParams, &errCode);
if (canHandle == NULL)
{
System_printf ("Error: CAN Module Initialization failed [Error code %d]\n", errCode);
return -1;
}
/* Set the desired bit rate based on input clock */
retVal = DCANAppCalcBitTimeParams(DCAN_APP_INPUT_CLK / 1000000,
DCAN_APP_BIT_RATE / 1000,
DCAN_APP_SAMP_PT,
DCAN_APP_PROP_DELAY,
&appDcanBitTimeParams);
if (retVal < 0)
{
System_printf ("Error: CAN Module bit time parameters are incorrect \n");
return -1;
}
/* Configure the CAN driver */
retVal = CAN_configBitTime (canHandle, &appDcanBitTimeParams, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN Module configure bit time failed [Error code %d]\n", errCode);
return -1;
}
/* Setup the transmit message object */
txMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_TX_MSG_OBJ, &appDcanTxCfgParams, &errCode);
if (txMsgObjHandle == NULL)
{
System_printf ("Error: CAN create Tx message object failed [Error code %d]\n", errCode);
return -1;
}
/* Setup the receive message object */
rxMsgObjHandle = CAN_createMsgObject (canHandle, DCAN_RX_MSG_OBJ, &appDcanRxCfgParams, &errCode);
if (rxMsgObjHandle == NULL)
{
System_printf ("Error: CAN create Rx message object failed [Error code %d]\n", errCode);
return -1;
}
while (1)
{
/* Send data over Tx message object */
retVal = CAN_transmitData (txMsgObjHandle, &appDcanTxData, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN transmit data for iteration %d failed [Error code %d]\n", iterationCount, errCode);
return -1;
}
iterationCount++;
if (gDisplayStats == 1)
{
gDisplayStats = 0;
if (((msgLstErrCnt == 0) &&
(dataMissMatchErrCnt == 0)) && (retVal == 0))
{
System_printf("Debug: External transmit testing Passed\n");
}
else
{
System_printf("Debug: External transmit testing failed\n");
retVal = -1;
}
System_printf("Debug: Number of iterations : %d\n", iterationCount);
System_printf("Debug: Number of messages transmitted : %d\n", gTxPkts);
System_printf("Debug: Number of messages received : %d\n", gRxPkts);
System_printf("Debug: Number of messages lost : %d\n", msgLstErrCnt);
System_printf("Debug: Error Status Interrupt : %d\n", gErrStatusInt);
System_printf("\n\n");
msgObjStats.handle = txMsgObjHandle;
optionTLV.type = CAN_Option_DCAN_MSG_OBJECT_STATS;
optionTLV.length = sizeof(CAN_DCANMsgObjectStats);
optionTLV.value = (void*) &msgObjStats;
retVal = CAN_getOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN get stats failed [Error code %d]\n", errCode);
}
System_printf("Debug: Message object number : %d\n", msgObjStats.msgObjectNum);
System_printf("Debug: Direction : %s\n", (msgObjStats.direction == 0) ? "Receive" : "Transmit");
System_printf("Debug: Number of interrupts received : %d\n", msgObjStats.interruptsRxed);
System_printf("Debug: Number of messages processed : %d\n", msgObjStats.messageProcessed);
System_printf("\n\n");
msgObjStats.handle = rxMsgObjHandle;
retVal = CAN_getOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN get stats failed [Error code %d]\n", errCode);
}
System_printf("Debug: Message object number : %d\n", msgObjStats.msgObjectNum);
System_printf("Debug: Direction : %s\n", (msgObjStats.direction == 0) ? "Receive" : "Transmit");
System_printf("Debug: Number of interrupts received : %d\n", msgObjStats.interruptsRxed);
System_printf("Debug: Number of messages processed : %d\n", msgObjStats.messageProcessed);
System_printf("\n\n");
optionTLV.type = CAN_Option_DCAN_ERROR_COUNTER;
optionTLV.length = sizeof(CAN_DCANErrorCounter);
optionTLV.value = (void*) &errCounter;
retVal = CAN_getOptions(canHandle, &optionTLV, &errCode);
if (retVal < 0)
{
System_printf ("Error: CAN get error counter failed [Error code %d]\n", errCode);
}
System_printf("Debug: Receive passive error : %d\n", errCounter.rxErrPassive);
System_printf("Debug: Transmit Error Counter : %d\n", errCounter.txErrCounter);
System_printf("Debug: Receive Error Counter : %d\n", errCounter.rxErrCounter);
}
}
}
/**************************************************************************
*************************** Global Definitions ***************************
**************************************************************************/
/**
* @brief
* Global Variable for tracking information required by the SRR TI Design
*/
#pragma DATA_ALIGN(gSrrMSSMCB, 16);
Srr_MSS_MCB gSrrMSSMCB;
/**************************************************************************
*************************** Local Definitions ****************************
**************************************************************************/
static void SRR_MSS_chirpIntCallback(uintptr_t arg);
static void SRR_MSS_frameStartIntCallback(uintptr_t arg);
static int32_t SRR_MSS_eventFxn(uint16_t msgId, uint16_t sbId, uint16_t sbLen, uint8_t *payload);
static void SRR_MSS_cfgFxn(MMWave_CtrlCfg* ptrCtrlCfg);
static void SRR_MSS_startFxn(MMWave_CalibrationCfg* ptrCalibrationCfg);
static void SRR_MSS_stopFxn(void);
static void SRR_MSS_initTask (UArg arg0, UArg arg1);
static void SRR_MSS_mmWaveCtrlTask (UArg arg0, UArg arg1);
#ifdef USE_LVDS_INTERFACE_FOR_OBJECT_DATA_TX
static int32_t SRR_MSS_configureStreaming();
static int32_t SRR_MSS_EDMAAllocateCBUFFChannel (CBUFF_EDMAInfo* ptrEDMAInfo, CBUFF_EDMAChannelCfg* ptrEDMACfg);
static void SRR_MSS_EDMAFreeCBUFFChannel(CBUFF_EDMAChannelCfg* ptrEDMACfg);
static EDMA_Handle SRR_MSS_openEDMA(uint8_t instance);
int32_t SRR_MSS_initEDMA(uint8_t instance);
static void SRR_MSS_edmaErrorCallbackFxn(EDMA_Handle handle, EDMA_errorInfo_t* errorInfo);
static void SRR_MSS_edmaTransferControllerErrorCallbackFxn(EDMA_Handle handle,
EDMA_transferControllerErrorInfo_t* errorInfo);
/*! @brief
* The global variable gwSwUserBuffer will be filled with the object data, and send over LVDS. The
* size of thar array is determined by the largest message possible and is given by
* Header, TLV (3 of them) + 'detected objects' + cluster + trackers + parking Assist.*/
#pragma DATA_ALIGN(gSwUserBuffer, 32);
volatile uint16_t gSwUserBuffer[2048];
#endif
/**************************************************************************
********************** MSS SRR TI Design Functions ***********************
**************************************************************************/
/**
* @b Description
* @n
* This is the callback function registered with the ADC Driver which is invoked
* when a chirp is available. This is executed in the ISR context.
*
* @param[in] arg
* Application registered argument
*
* @retval
* Not Applicable.
*/
static void SRR_MSS_chirpIntCallback(uintptr_t arg)
{
gSrrMSSMCB.chirpInt++;
gSrrMSSMCB.chirpIntcumSum++;
/* The different subframes in the SRR configuration have different chirp sizes.
* These need to be configured before the start of the next subframe, at the
* end of the previous subframes last chirp. */
if (gSrrMSSMCB.chirpInt == gSrrMSSMCB.numChirpsPerSubframe[gSrrMSSMCB.subframeId])
{
gSrrMSSMCB.subframeCntFromChirpInt++;
gSrrMSSMCB.subframeId = gSrrMSSMCB.subframeId + 1;
if (gSrrMSSMCB.subframeId == NUM_SUBFRAMES)
{
gSrrMSSMCB.subframeId = 0;
}
gSrrMSSMCB.chirpInt = 0;
}
}
/**
* @b Description
* @n
* This is the callback function registered with the ADC Driver which is invoked
* when a frame is started. This is executed in the ISR context.
*
* @param[in] arg
* Application registered argument
*
* @retval
* Not Applicable.
*/
static void SRR_MSS_frameStartIntCallback(uintptr_t arg)
{
gSrrMSSMCB.frameStartToken++;
gSrrMSSMCB.subframeCntFromFrameStart++;
/* Check if the frames are coming correctly, and no chirps have been missed. */
if (gSrrMSSMCB.frameStartToken == 1)
{
if (gSrrMSSMCB.chirpInt == 0)
{
gSrrMSSMCB.frameStartToken = 0;
}
else
{
DebugP_assert (0);
}
}
}
/**
* @b Description
* @n
* Registered event function which is invoked when an event from the
* BSS is received.
*
* @param[in] msgId
* Message Identifier
* @param[in] sbId
* Subblock identifier
* @param[in] sbLen
* Length of the subblock
* @param[in] payload
* Pointer to the payload buffer
*
* @retval
* Always returns 0 [Continue passing the event to the peer domain]
*/
static int32_t SRR_MSS_eventFxn(uint16_t msgId, uint16_t sbId, uint16_t sbLen, uint8_t *payload)
{
uint16_t asyncSB = RL_GET_SBID_FROM_UNIQ_SBID(sbId);
/* Process the received message: */
switch (msgId)
{
case RL_RF_ASYNC_EVENT_MSG:
{
/* Received Asychronous Message: */
switch (asyncSB)
{
case RL_RF_AE_CPUFAULT_SB:
{
/* Post event to datapath task notify BSS events */
//Event_post(gSrrMSSMCB.eventHandle, MMWDEMO_BSS_CPUFAULT_EVT);
break;
}
case RL_RF_AE_ESMFAULT_SB:
{
/* Post event to datapath task notify BSS events */
//Event_post(gSrrMSSMCB.eventHandle, MMWDEMO_BSS_ESMFAULT_EVT);
break;
}
case RL_RF_AE_INITCALIBSTATUS_SB:
{
/* This event should be handled by mmwave internally, ignore the event here */
break;
}
case RL_RF_AE_FRAME_TRIGGER_RDY_SB:
{
break;
}
case RL_RF_AE_MON_TIMING_FAIL_REPORT_SB:
{
break;
}
case RL_RF_AE_RUN_TIME_CALIB_REPORT_SB:
{
break;
}
default:
{
System_printf ("Error: Asynchronous Event SB Id %d not handled\n", asyncSB);
break;
}
}
break;
}
default:
{
System_printf ("Error: Asynchronous message %d is NOT handled\n", msgId);
break;
}
}
return 0;
}
/**
* @b Description
* @n
* This is the application registered callback function which is invoked after
* the configuration has been used to configure the mmWave link and the BSS.
*
* @param[in] ptrCtrlCfg
* Pointer to the control configuration
*
* @retval
* Not applicable
*/
static void SRR_MSS_cfgFxn(MMWave_CtrlCfg* ptrCtrlCfg)
{
/* The SRR TI Design operates in MINIMAL mode and so the configuration
* callback function is never invoked. The assertion will ensure that
* this is never invoked */
DebugP_assert (0);
}
/**
* @b Description
* @n
* Application registered callback function which is invoked the mmWave link on BSS
* has been started. This is applicable only for the XWR16xx. The BSS can be configured
* only by the MSS *or* DSS. The callback API is triggered on the remote execution
* domain (which did not configure the BSS)
*
* @param[in] ptrCalibrationCfg
* Pointer to the calibrat ion configuration
*
* @retval
* Not applicable
*/
static void SRR_MSS_startFxn(MMWave_CalibrationCfg* ptrCalibrationCfg)
{
/* Post an event to main data path task.
This function in only called when mmwave_start() is called on DSS */
gSrrMSSMCB.stats.datapathStartEvt ++;
/* Post event to start is done */
Event_post(gSrrMSSMCB.eventHandleNotify, MMWDEMO_DSS_START_COMPLETED_EVT);
}
/**
* @b Description
* @n
* This is the application registered callback function which is invoked after the
* has been stopped. This is applicable only for the XWR16xx. The BSS can be configured
* only by the MSS *or* DSS. The callback API is triggered on the remote execution
* mmWave link on BSS has been stopped.
*
* @retval
* Not applicable
*/
static void SRR_MSS_stopFxn(void)
{
/* Possible sceanarios:
1. CLI sensorStop command triggers mmwave_stop() to be called from MSS
2. In case of Error, mmwave_stop() will be triggered either from MSS or DSS
*/
gSrrMSSMCB.stats.datapathStopEvt ++;
}
/**
* @b Description
* @n
* Application registered callback function which is invoked the mmWave link on BSS
* has been opened.
*
* @param[in] ptrOpenCfg
* Pointer to the open configuration
*
* @retval
* Not applicable
*/
static void SRR_MSS_openFxn(MMWave_OpenCfg* ptrOpenCfg)
{
return;
}
/**
* @b Description
* @n
* Application registered callback function which is invoked the mmWave link on BSS
* has been closed.
*
* @retval
* Not applicable
*/
static void SRR_MSS_closeFxn(void)
{
return;
}
/**
* @b Description
* @n
* Function to send a message to peer through Mailbox virtural channel
*
* @param[in] message
* Pointer to the MMW demo message.
*
* @retval
* Success - 0
* Fail < -1
*/
int32_t MmwDemo_mboxWrite(MmwDemo_message * message)
{
int32_t retVal = -1;
retVal = Mailbox_write (gSrrMSSMCB.peerMailbox, (uint8_t*)message, sizeof(MmwDemo_message));
if (retVal == sizeof(MmwDemo_message))
{
retVal = 0;
}
return retVal;
}
/**
* @b Description
* @n
* The Task is used to handle the mmw demo messages received from
* Mailbox virtual channel.
*
* @param[in] arg0
* arg0 of the Task. Not used
* @param[in] arg1
* arg1 of the Task. Not used
*
* @retval
* Not Applicable.
*/
static void MmwDemo_mboxReadTask(UArg arg0, UArg arg1)
{
MmwDemo_message message;
int32_t retVal = 0;
/* wait for new message and process all the messsages received from the peer */
while(1)
{
Semaphore_pend(gSrrMSSMCB.mboxSemHandle, BIOS_WAIT_FOREVER);
/* Read the message from the peer mailbox: We are not trying to protect the read
* from the peer mailbox because this is only being invoked from a single thread */
retVal = Mailbox_read(gSrrMSSMCB.peerMailbox, (uint8_t*)&message, sizeof(MmwDemo_message));
if (retVal < 0)
{
/* Error: Unable to read the message. Setup the error code and return values */
System_printf ("Error: Mailbox read failed [Error code %d]\n", retVal);
}
else if (retVal == 0)
{
/* We are done: There are no messages available from the peer execution domain. */
continue;
}
else
{
/* Flush out the contents of the mailbox to indicate that we are done with the message. This will
* allow us to receive another message in the mailbox while we process the received message. */
Mailbox_readFlush (gSrrMSSMCB.peerMailbox);
/* Process the received message: */
switch (message.type)
{
case MMWDEMO_DSS2MSS_DETOBJ_READY:
/* Got detected objects , to be shipped out shipped out through UART */
#ifdef USE_LVDS_INTERFACE_FOR_OBJECT_DATA_TX
{
int32_t errCode;
volatile uint32_t totalPacketLen = 0;
uint32_t itemIdx;
uint8_t *swUserBuffer = (uint8_t *)&gSwUserBuffer[0];
/* header */
memcpy(&swUserBuffer[totalPacketLen], (uint8_t*)&message.body.detObj.header, sizeof(MmwDemo_output_message_header));
totalPacketLen = sizeof(MmwDemo_output_message_header);
/* TLVs */
for (itemIdx = 0; itemIdx < message.body.detObj.header.numTLVs; itemIdx++)
{
memcpy(&swUserBuffer[totalPacketLen], (uint8_t*)&message.body.detObj.tlv[itemIdx], sizeof(MmwDemo_output_message_tl));
totalPacketLen += sizeof(MmwDemo_output_message_tl);
memcpy(&swUserBuffer[totalPacketLen],
(uint8_t*)SOC_translateAddress(message.body.detObj.tlv[itemIdx].address,
SOC_TranslateAddr_Dir_FROM_OTHER_CPU,NULL), message.body.detObj.tlv[itemIdx].length);
totalPacketLen += message.body.detObj.tlv[itemIdx].length;
}
DebugP_assert(totalPacketLen < sizeof(gSwUserBuffer));
/* Deactivate the hardware session */
DebugP_assert (CBUFF_deactivateSession (gSrrMSSMCB.swSessionHandle, &errCode) == 0);
/* Activate the hardware session */
DebugP_assert (CBUFF_activateSession (gSrrMSSMCB.swSessionHandle, &errCode) == 0);
}
#else
{
uint32_t totalPacketLen;
uint32_t numPaddingBytes;
uint32_t itemIdx;
/* Send header */
totalPacketLen = sizeof(MmwDemo_output_message_header);
UART_writePolling (gSrrMSSMCB.loggingUartHandle,
(uint8_t*)&message.body.detObj.header,
sizeof(MmwDemo_output_message_header));
/* Send TLVs */
for (itemIdx = 0; itemIdx < message.body.detObj.header.numTLVs; itemIdx++)
{
UART_writePolling (gSrrMSSMCB.loggingUartHandle,
(uint8_t*)&message.body.detObj.tlv[itemIdx],
sizeof(MmwDemo_output_message_tl));
UART_writePolling (gSrrMSSMCB.loggingUartHandle,
(uint8_t*)SOC_translateAddress(message.body.detObj.tlv[itemIdx].address,
SOC_TranslateAddr_Dir_FROM_OTHER_CPU,NULL),
message.body.detObj.tlv[itemIdx].length);
totalPacketLen += sizeof(MmwDemo_output_message_tl) + message.body.detObj.tlv[itemIdx].length;
}
/* Send padding to make total packet length multiple of MMWDEMO_OUTPUT_MSG_SEGMENT_LEN */
numPaddingBytes = MMWDEMO_OUTPUT_MSG_SEGMENT_LEN - (totalPacketLen & (MMWDEMO_OUTPUT_MSG_SEGMENT_LEN-1));
if (numPaddingBytes<MMWDEMO_OUTPUT_MSG_SEGMENT_LEN)
{
uint8_t padding[MMWDEMO_OUTPUT_MSG_SEGMENT_LEN];
/*DEBUG:*/ memset(&padding, 0xf, MMWDEMO_OUTPUT_MSG_SEGMENT_LEN);
UART_writePolling (gSrrMSSMCB.loggingUartHandle, padding, numPaddingBytes);
}
}
#endif
/* Send a message to MSS to log the output data */
memset((void *)&message, 0, sizeof(MmwDemo_message));
message.type = MMWDEMO_MSS2DSS_DETOBJ_SHIPPED;
retVal = MmwDemo_mboxWrite(&message);
if (retVal != 0)
{
System_printf ("Error: Mailbox send message id=%d failed \n", message.type);
}
break;
case MMWDEMO_DSS2MSS_ASSERT_INFO:
/* Send the received DSS assert info through CLI */
CLI_write ("DSS Exception: %s, line %d.\n", message.body.assertInfo.file,
message.body.assertInfo.line);
break;
default:
{
/* Message not support */
System_printf ("Error: unsupport Mailbox message id=%d\n", message.type);
break;
}
}
}
}
}
/**
* @b Description
* @n
* This function is a callback funciton that invoked when a message is received from the peer.
*
* @param[in] handle
* Handle to the Mailbox on which data was received
* @param[in] peer
* Peer from which data was received
* @retval
* Not Applicable.
*/
void MmwDemo_mboxCallback
(
Mbox_Handle handle,
Mailbox_Type peer
)
{
/* Message has been received from the peer endpoint. Wakeup the mmWave thread to process
* the received message. */
Semaphore_post (gSrrMSSMCB.mboxSemHandle);
}
/**
* @b Description
* @n
* This is the task which provides an execution context for
* the mmWave control module.
*
* @param[in] arg0
* Argument0 with which the task was created
* @param[in] arg1
* Argument1 with which the task was created
*
* @retval
* Not Applicable.
*/
static void SRR_MSS_mmWaveCtrlTask (UArg arg0, UArg arg1)
{
int32_t errCode;
while (1)
{
/* Execute the mmWave control module: */
if (MMWave_execute (gSrrMSSMCB.ctrlHandle, &errCode) < 0)
{
System_printf ("Error: mmWave control execution failed [Error code %d]\n", errCode);
}
}
}
/**
* @b Description
* @n
* Callback function invoked when the GPIO switch is pressed.
* This is invoked from interrupt context.
*
* @param[in] index
* GPIO index configured as input
*
* @retval
* Not applicable
*/
static void SRR_MSS_switchPressFxn(unsigned int index)
{
}
/**
* @b Description
* @n
* The task is used to process data path events
* control task
*
* @retval
* Not Applicable.
*/
void SRR_MSS_mssProcessDataPathTask(UArg arg0, UArg arg1)
{
UInt event = 0;
/**********************************************************************
* Setup the PINMUX:
* - GPIO Input : Configure pin J13 as GPIO_1 input
* - GPIO Output: Configure pin K13 as GPIO_2 output
**********************************************************************/
Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINJ13_PADAC, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINJ13_PADAC, SOC_XWR16XX_PINJ13_PADAC_GPIO_1);
Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINK13_PADAZ, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINK13_PADAZ, SOC_XWR16XX_PINK13_PADAZ_GPIO_2);
/**********************************************************************
* Setup the SW1 switch on the EVM connected to GPIO_1
* - This is used as an input
* - Enable interrupt to be notified on a switch press
**********************************************************************/
GPIO_setConfig (SOC_XWR16XX_GPIO_1, GPIO_CFG_INPUT | GPIO_CFG_IN_INT_RISING | GPIO_CFG_IN_INT_LOW);
GPIO_setCallback (SOC_XWR16XX_GPIO_1, SRR_MSS_switchPressFxn);
GPIO_enableInt (SOC_XWR16XX_GPIO_1);
/**********************************************************************
* Setup the DS3 LED on the EVM connected to GPIO_2
**********************************************************************/
GPIO_setConfig (SOC_XWR16XX_GPIO_2, GPIO_CFG_OUTPUT);
System_printf ("Debug: Data Path management main loop. \n");
/* Data Path management task Main loop */
while (1)
{
event = Event_pend(gSrrMSSMCB.eventHandle,
Event_Id_NONE,
MMWDEMO_CLI_EVENTS | MMWDEMO_BSS_FAULT_EVENTS,
BIOS_WAIT_FOREVER);
/************************************************************************
* BSS event:: CPU fault
************************************************************************/
if(event & MMWDEMO_BSS_CPUFAULT_EVT)
{
break;
}
/************************************************************************
* BSS event:: ESM fault
************************************************************************/
if(event & MMWDEMO_BSS_ESMFAULT_EVT)
{
break;
}
}
System_printf("Debug: MMWDemoDSS Data path exit\n");
}
/**
* @b Description
* @n
* MSS Initialization Task which initializes the various
* components in the MSS subsystem.
*
* @param[in] arg0
* Argument0 with which the task was created
* @param[in] arg1
* Argument1 with which the task was created
*
* @retval
* Not Applicable.
*/
static void SRR_MSS_initTask (UArg arg0, UArg arg1)
{
int32_t errCode;
MMWave_InitCfg initCfg;
UART_Params uartParams;
Task_Params taskParams;
SOC_SysIntListenerCfg listenerCfg;
Semaphore_Params semParams;
Mailbox_Config mboxCfg;
/* Debug Message: */
System_printf("Debug: Launched the Initialization Task\n");
/* Initialize the platform */
int32_t retVal = PlatformInit();
if (retVal < 0)
{
System_printf("Error: Unable to initialize platform CAN\n");
BIOS_exit(0);
}
/*****************************************************************************
* Initialize the mmWave SDK components:
*****************************************************************************/
/* Pinmux setting */
/* Setup the PINMUX to bring out the UART-1 */
Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINN5_PADBE, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINN5_PADBE, SOC_XWR16XX_PINN5_PADBE_MSS_UARTA_TX);
Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINN4_PADBD, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINN4_PADBD, SOC_XWR16XX_PINN4_PADBD_MSS_UARTA_RX);
/* Setup the PINMUX to bring out the UART-3 */
Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINF14_PADAJ, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINF14_PADAJ, SOC_XWR16XX_PINF14_PADAJ_MSS_UARTB_TX);
/* Setup the PINMUX to bring out the DSS UART */
Pinmux_Set_OverrideCtrl(SOC_XWR16XX_PINP8_PADBM, PINMUX_OUTEN_RETAIN_HW_CTRL, PINMUX_INPEN_RETAIN_HW_CTRL);
Pinmux_Set_FuncSel(SOC_XWR16XX_PINP8_PADBM, SOC_XWR16XX_PINP8_PADBM_DSS_UART_TX);
/* Initialize the UART */
UART_init();
/* Initialize the GPIO */
GPIO_init();
/* Initialize the Mailbox */
Mailbox_init(MAILBOX_TYPE_MSS);
/* Open UART Driver: */
UART_Params_init(&uartParams);
uartParams.clockFrequency = MSS_SYS_VCLK;
uartParams.baudRate = 115200;
uartParams.isPinMuxDone = 1;
/* Open the Command UART Instance */
gSrrMSSMCB.commandUartHandle = UART_open(0, &uartParams);
if (gSrrMSSMCB.commandUartHandle == NULL)
{
System_printf("Error: Unable to open the Command UART Instance\n");
return;
}
/* Setup the default UART Parameters */
UART_Params_init(&uartParams);
uartParams.writeDataMode = UART_DATA_BINARY;
uartParams.readDataMode = UART_DATA_BINARY;
uartParams.clockFrequency = MSS_SYS_VCLK;
uartParams.baudRate = 115200*8;
uartParams.isPinMuxDone = 1U;
/* Open the Logging UART Instance: */
gSrrMSSMCB.loggingUartHandle = UART_open(1, &uartParams);
if (gSrrMSSMCB.loggingUartHandle == NULL)
{
System_printf("Error: MMWDemoMSS Unable to open the Logging UART Instance\n");
return;
}
/*****************************************************************************
* Creating communication channel between MSS & DSS
*****************************************************************************/
/* Create a binary semaphore which is used to handle mailbox interrupt. */
Semaphore_Params_init(&semParams);
semParams.mode = Semaphore_Mode_BINARY;
gSrrMSSMCB.mboxSemHandle = Semaphore_create(0, &semParams, NULL);
/* Setup the default mailbox configuration */
Mailbox_Config_init(&mboxCfg);
/* Setup the configuration: */
mboxCfg.chType = MAILBOX_CHTYPE_MULTI;
mboxCfg.chId = MAILBOX_CH_ID_0;
mboxCfg.writeMode = MAILBOX_MODE_BLOCKING;
mboxCfg.readMode = MAILBOX_MODE_CALLBACK;
mboxCfg.readCallback = &MmwDemo_mboxCallback;
/* Initialization of Mailbox Virtual Channel */
gSrrMSSMCB.peerMailbox = Mailbox_open(MAILBOX_TYPE_DSS, &mboxCfg, &errCode);
if (gSrrMSSMCB.peerMailbox == NULL)
{
/* Error: Unable to open the mailbox */
System_printf("Error: Unable to open the Mailbox to the DSS [Error code %d]\n", errCode);
return;
}
/* Create task to handle mailbox messages */
Task_Params_init(&taskParams);
taskParams.stackSize = 16*1024;
Task_create(MmwDemo_mboxReadTask, &taskParams, NULL);
/* Register Chirp Available Listener */
memset ((void*)&listenerCfg, 0, sizeof(SOC_SysIntListenerCfg));
listenerCfg.systemInterrupt = SOC_XWR16XX_MSS_CHIRP_AVAIL_IRQ;
listenerCfg.listenerFxn = SRR_MSS_chirpIntCallback;
listenerCfg.arg = 0;
gSrrMSSMCB.chirpIntHandle = SOC_registerSysIntListener (gSrrMSSMCB.socHandle, &listenerCfg, &errCode);
if (gSrrMSSMCB.chirpIntHandle == NULL)
{
System_printf ("Error: Unable to register the Chirp Available Listener [Error code %d]\n", errCode);
return;
}
/* Register Frame Start Listener */
memset ((void*)&listenerCfg, 0, sizeof(SOC_SysIntListenerCfg));
listenerCfg.systemInterrupt = SOC_XWR16XX_MSS_FRAME_START_INT;
listenerCfg.listenerFxn = SRR_MSS_frameStartIntCallback;
listenerCfg.arg = 0;
gSrrMSSMCB.frameStartIntHandle = SOC_registerSysIntListener (gSrrMSSMCB.socHandle, &listenerCfg, &errCode);
if (gSrrMSSMCB.frameStartIntHandle == NULL)
{
System_printf("Error: Unable to register the Frame start Listener [Error code %d]\n", errCode);
return ;
}
/*****************************************************************************
* Initialize the mmWave module:
*****************************************************************************/
memset ((void *)&initCfg, 0, sizeof(MMWave_InitCfg));
/* Populate the initialization configuration:
* The MMWAve is configured in minimal isolation mode. */
initCfg.domain = MMWave_Domain_MSS;
initCfg.socHandle = gSrrMSSMCB.socHandle;
initCfg.eventFxn = &SRR_MSS_eventFxn;
initCfg.cfgMode = MMWave_ConfigurationMode_MINIMAL;
initCfg.executionMode = MMWave_ExecutionMode_ISOLATION;
initCfg.linkCRCCfg.useCRCDriver = 1U;
initCfg.linkCRCCfg.crcChannel = CRC_Channel_CH1;
initCfg.cooperativeModeCfg.cfgFxn = &SRR_MSS_cfgFxn;
initCfg.cooperativeModeCfg.startFxn = &SRR_MSS_startFxn;
initCfg.cooperativeModeCfg.stopFxn = &SRR_MSS_stopFxn;
initCfg.cooperativeModeCfg.openFxn = &SRR_MSS_openFxn;
initCfg.cooperativeModeCfg.closeFxn = &SRR_MSS_closeFxn;
/* Initialize and setup the mmWave Control module */
gSrrMSSMCB.ctrlHandle = MMWave_init (&initCfg, &errCode);
if (gSrrMSSMCB.ctrlHandle == NULL)
{
/* Error: Unable to initialize the mmWave control module */
System_printf ("Error: mmWave Control Initialization failed [Error code %d]\n", errCode);
return;
}
System_printf ("Debug: Initialized the mmWave module\n");
/*****************************************************************************
* Synchronize the mmWave module:
*****************************************************************************/
while (1)
{
int32_t syncStatus;
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
System_printf("Debug: parity testing\n");
retVal = dcanParityTest();
if (retVal == -1)
System_printf("Debug: parity testing FAIL\n");
else
System_printf("Debug: parity testing PASS\n");
/*--------------------------------------------------------------*/
/*--------------------------------------------------------------*/
/* Get the synchronization status: */
syncStatus = MMWave_sync (gSrrMSSMCB.ctrlHandle, &errCode);
if (syncStatus < 0)
{
/* Error: Unable to synchronize the mmWave control module */
System_printf ("Error: mmWave Control Synchronization failed [Error code %d]\n", errCode);
return;
}
if (syncStatus == 1)
{
/* Synchronization acheived: */
break;
}
/* Sleep and poll again: */
Task_sleep(1);
}
System_printf ("Debug: Synchronized the mmWave module\n");
#ifdef SUBFRAME_CONF_SRR_USRR
gSrrMSSMCB.numChirpsPerSubframe[0] = SUBFRAME_SRR_NUM_CHIRPS_TOTAL;
gSrrMSSMCB.numChirpsPerSubframe[1] = SUBFRAME_USRR_NUM_CHIRPS_TOTAL;
#else
#ifdef SUBFRAME_CONF_SRR
gSrrMSSMCB.numChirpsPerSubframe[0] = SUBFRAME_SRR_NUM_CHIRPS_TOTAL;
#endif
#ifdef SUBFRAME_CONF_USRR
gSrrMSSMCB.numChirpsPerSubframe[0] = SUBFRAME_USRR_NUM_CHIRPS_TOTAL;
#endif
#endif
#ifdef USE_LVDS_INTERFACE_FOR_OBJECT_DATA_TX
/* Configure the LVDS streaming interface.*/
{
int32_t streamConfiguration = SRR_MSS_configureStreaming() ;
if (streamConfiguration != 0)
{
System_printf ("Error: Unable to activate the Streaming Session [Error code %d]\n", streamConfiguration);
DebugP_assert (0);
}
}
#endif
/*****************************************************************************
* Launch the mmWave control execution task
* - This should have a higher priroity than any other task which uses the
* mmWave control API
*****************************************************************************/
Task_Params_init(&taskParams);
taskParams.priority = 6;
taskParams.stackSize = 3*1024;
Task_create(SRR_MSS_mmWaveCtrlTask, &taskParams, NULL);
/*****************************************************************************
* Setup the CLI
*****************************************************************************/
SRR_MSS_CLIInit ();
}
/**
* @b Description
* @n
* Entry point into the MSS TI Design
*
* @retval
* Not Applicable.
*/
int32_t main (void)
{
Task_Params taskParams;
int32_t errCode;
SOC_Cfg socCfg;
/* Initialize the ESM: Dont clear errors as TI RTOS does it */
ESM_init(0U);
/* Initialize the global variables */
memset ((void*)&gSrrMSSMCB, 0, sizeof(Srr_MSS_MCB));
/* Initialize the SOC configuration: */
memset ((void *)&socCfg, 0, sizeof(SOC_Cfg));
/* Populate the SOC configuration: */
socCfg.clockCfg = SOC_SysClock_INIT;
/* Initialize the SOC Module: This is done as soon as the application is started
* to ensure that the MPU is correctly configured. */
gSrrMSSMCB.socHandle = SOC_init (&socCfg, &errCode);
if (gSrrMSSMCB.socHandle == NULL)
{
System_printf ("Error: SOC Module Initialization failed [Error code %d]\n", errCode);
return -1;
}
/* Initialize the Task Parameters. */
Task_Params_init(&taskParams);
taskParams.priority = 3;
Task_create(SRR_MSS_initTask, &taskParams, NULL);
/* Start BIOS */
BIOS_start();
return 0;
}
#ifdef USE_LVDS_INTERFACE_FOR_OBJECT_DATA_TX
/**
* @b Description
* @n
* The function is used to configure the CBUFF/LVDS Streaming
*
* @param[in] ptrDataPathObj
* Handle to data Path object
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
static int32_t SRR_MSS_configureStreaming()
{
CBUFF_InitCfg initCfg;
CBUFF_SessionCfg sessionCfg;
rlDevHsiClk_t hsiClkgs;
int32_t errCode;
int32_t retVal = -1;
/* Initialize the CBUFF Initialization configuration: */
memset ((void *)&initCfg, 0, sizeof(CBUFF_InitCfg));
/* Populate the configuration: */
initCfg.socHandle = gSrrMSSMCB.socHandle;
initCfg.enableECC = 0U;
initCfg.crcEnable = 1U;
initCfg.maxSessions = 1U;
initCfg.enableDebugMode = false;
initCfg.interface = CBUFF_Interface_LVDS;
initCfg.u.lvdsCfg.crcEnable = 0U;
initCfg.u.lvdsCfg.msbFirst = 1U;
initCfg.u.lvdsCfg.lvdsLaneEnable = 0x3U;
initCfg.u.lvdsCfg.ddrClockMode = 1U;
initCfg.u.lvdsCfg.ddrClockModeMux= 1U;
/*****************************************************************************
* Initialize EDMA driver
*****************************************************************************/
if (SRR_MSS_initEDMA(CBUFF_EDMA_INSTANCE) < 0)
{
return -1;
}
/*****************************************************************************
* Open EDMA driver:
*****************************************************************************/
if( (gSrrMSSMCB.dmaHandle = SRR_MSS_openEDMA(CBUFF_EDMA_INSTANCE) )== NULL)
{
return -2;
}
/* Translate the data format from the mmWave link to the CBUFF: */
/* 16bit Data Output Format: */
initCfg.outputDataFmt = CBUFF_OutputDataFmt_16bit;
/* Initialize the CBUFF Driver: */
gSrrMSSMCB.cbuffHandle = CBUFF_init (&initCfg, &errCode);
if (gSrrMSSMCB.cbuffHandle == NULL)
{
/* Error: Unable to initialize the CBUFF; report the error */
System_printf ("Error: CBUFF Driver initialization failed [Error code %d]\n", errCode);
goto exit;
}
/********************************************************************************
* Software Triggered Session:
********************************************************************************/
{
/* Initialize the session configuration: */
memset ((void*)&sessionCfg, 0, sizeof(CBUFF_SessionCfg));
/* Populate the configuration: */
sessionCfg.executionMode = CBUFF_SessionExecuteMode_SW;
sessionCfg.edmaHandle = gSrrMSSMCB.dmaHandle;
sessionCfg.allocateEDMAChannelFxn = SRR_MSS_EDMAAllocateCBUFFChannel;
sessionCfg.freeEDMAChannelFxn = SRR_MSS_EDMAFreeCBUFFChannel;
sessionCfg.frameDoneCallbackFxn = NULL;
sessionCfg.dataType = CBUFF_DataType_REAL;
sessionCfg.u.swCfg.headerMode = CBUFF_HeaderMode_NONE;
sessionCfg.u.swCfg.userBufferInfo[0].size = sizeof(gSwUserBuffer)/2;
sessionCfg.u.swCfg.userBufferInfo[0].address = (uint32_t)&gSwUserBuffer[0];
/* Create the session: */
gSrrMSSMCB.swSessionHandle = CBUFF_createSession (gSrrMSSMCB.cbuffHandle, &sessionCfg, &errCode);
if (gSrrMSSMCB.swSessionHandle == NULL)
{
System_printf ("Error: Unable to create the CBUFF Session [Error code %d]\n", errCode);
retVal = -3;
goto exit;
}
}
/*************************************************************************************
* Setup the HSI Clock through the mmWave Link:
*************************************************************************************/
memset ((void*)&hsiClkgs, 0, sizeof(rlDevHsiClk_t));
/* Setup the HSI Clock as per the Radar Interface Document: This is set to 600Mhtz DDR Mode */
hsiClkgs.hsiClk = 0x9;
/* Setup the HSI in the radar link: */
retVal = rlDeviceSetHsiClk(RL_DEVICE_MAP_CASCADED_1, &hsiClkgs);
if (retVal != RL_RET_CODE_OK)
{
/* Error: Unable to set the HSI clock */
System_printf ("Error: Setting up the HSI Clock in BSS Failed [Error %d]\n", retVal);
goto exit;
}
{
/******************************************************************************
* ----------------------------------------------------------------------------
* Use Case 3: Hardware sessions is DISABLED and Software session is ENABLED
* ----------------------------------------------------------------------------
* 1) Activate SW Session
* 2) Frame Done on SW Session
* -> Do nothing.
* This is to simulate a use case where only the application debug data is
* being streamed out. So we kaunch the software session trigger task which
* will send out the data periodically. Activate the software session
******************************************************************************/
if (CBUFF_activateSession (gSrrMSSMCB.swSessionHandle, &errCode) < 0)
{
System_printf ("Error: Unable to activate the CBUFF Session [Error code %d]\n", errCode);
retVal = -4;
goto exit;
}
}
/* Setup the return value as the CBUFF streaming has been configured successfully */
retVal = 0;
exit:
return retVal;
}
/**
* @b Description
* @n
* This is the registered CBUFF EDMA channel allocation function which allocates
* EDMA channels for HW Triggered sessions
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
static int32_t SRR_MSS_EDMAAllocateCBUFFChannel (CBUFF_EDMAInfo* ptrEDMAInfo, CBUFF_EDMAChannelCfg* ptrEDMACfg)
{
/* Use the DMA Information to perform the CBUFF EDMA allocations */
if (ptrEDMAInfo->dmaNum == 0U)
{
ptrEDMACfg->chainChannelsId = SRR_CBUFF_EDMA_CH;
ptrEDMACfg->shadowLinkChannelsId = SRR_CBUFF_EDMA_SHADOW_CH;
}
else
{
/* Error: SRR only supports a single session (i.e. DMA-0)*/
DebugP_assert (0);
}
return 0;
}
/**
* @b Description
* @n
* This is the registered CBUFF EDMA channel free function which frees allocated
* EDMA channels for HW Triggered sessions
*
* @retval
* Not applicable
*/
static void SRR_MSS_EDMAFreeCBUFFChannel(CBUFF_EDMAChannelCfg* ptrEDMACfg)
{
return;
}
/**
* @b Description
* @n
* Open EDMA driver Instance for ADCBUF data buffer copy.
*
* @param[in] instance
* EDMA driver instance.
*
* @retval
* Success - EDMA handle
* Fail - NULL pointer
*/
static EDMA_Handle SRR_MSS_openEDMA(uint8_t instance)
{
EDMA_errorInfo_t EDMAErrorInfo;
EDMA_transferControllerErrorInfo_t EDMATransferControllerErrorInfo;
EDMA_Handle EdmaHandle = NULL;
EDMA_instanceInfo_t instanceInfo;
EDMA_errorConfig_t errorConfig;
int32_t retVal = 0;
memset(&EDMAErrorInfo, 0, sizeof(EDMAErrorInfo));
memset(&EDMATransferControllerErrorInfo, 0, sizeof(EDMATransferControllerErrorInfo));
/* Open the EDMA Instance */
EdmaHandle = EDMA_open(instance, &retVal, &instanceInfo);
if (EdmaHandle == NULL)
{
System_printf("Error: Unable to open the edma Instance(%d), errorCode = %d\n",instance, retVal);
return NULL;
}
/* Configurate EDMA Error Monitor */
errorConfig.isConfigAllEventQueues = true;
errorConfig.isConfigAllTransferControllers = true;
errorConfig.isEventQueueThresholdingEnabled = true;
errorConfig.eventQueueThreshold = EDMA_EVENT_QUEUE_THRESHOLD_MAX;
errorConfig.isEnableAllTransferControllerErrors = true;
errorConfig.callbackFxn = SRR_MSS_edmaErrorCallbackFxn;
errorConfig.transferControllerCallbackFxn = SRR_MSS_edmaTransferControllerErrorCallbackFxn;
if ((retVal = EDMA_configErrorMonitoring(EdmaHandle, &errorConfig)) != EDMA_NO_ERROR)
{
System_printf("Debug: EDMA_configErrorMonitoring() failed with errorCode = %d\n", retVal);
return NULL;
}
return EdmaHandle;
}
/**
* @b Description
* @n
* EDMA driver instance Initialization. Application is responsible for EDMA instance
* management.
*
* @param[in] instance
* EDMA driver instance.
*
* @retval
* Success - 0
* Fail - -1
*/
int32_t SRR_MSS_initEDMA(uint8_t instance)
{
int32_t retVal = 0;
retVal = EDMA_init(instance);
if (retVal != EDMA_NO_ERROR)
{
System_printf ("Debug: EDMA instance %d initialization returned error %d\n", instance, retVal);
return -1;
}
System_printf ("Debug: EDMA instance %d has been initialized\n", instance);
return 0;
}
/**
* @b Description
* @n
* Call back function for EDMA CC (Channel controller) error as per EDMA API.
* Declare fatal error if happens, the output errorInfo can be examined if code
* gets trapped here.
*
* @param[in] handle
* EDMA driver instance Handle
* @param[in] errorInfo
* EDMA Channle id used to copy data buffer
*
* @retval
* None
*/
static void SRR_MSS_edmaErrorCallbackFxn
(
EDMA_Handle handle,
EDMA_errorInfo_t* errorInfo
)
{
/* EDMA CC Error reported, Assert ? */
DebugP_assert(0);
}
/**
* @b Description
* @n
* Call back function for EDMA transfer controller error as per EDMA API.
* Declare fatal error if happens, the output errorInfo can be examined if code
* gets trapped here.
*
* @param[in] handle
* EDMA driver instance Handle
* @param[in] errorInfo
* EDMA Channle id used to copy data buffer
*
* @retval
* None
*/
static void SRR_MSS_edmaTransferControllerErrorCallbackFxn
(
EDMA_Handle handle,
EDMA_transferControllerErrorInfo_t* errorInfo
)
{
/* EDMA TC Error reported, Assert ? */
DebugP_assert(0);
}
#endif