/*
Copyright (c) [2012 - 2017] Texas Instruments Incorporated
All rights reserved not granted herein.
Limited License.
Texas Instruments Incorporated grants a world-wide, royalty-free, non-exclusive
license under copyrights and patents it now or hereafter owns or controls to
make, have made, use, import, offer to sell and sell ("Utilize") this software
subject to the terms herein. With respect to the foregoing patent license,
such license is granted solely to the extent that any such patent is necessary
to Utilize the software alone. The patent license shall not apply to any
combinations which include this software, other than combinations with devices
manufactured by or for TI ("TI Devices"). No hardware patent is licensed
hereunder.
Redistributions must preserve existing copyright notices and reproduce this
license (including the above copyright notice and the disclaimer and
(if applicable) source code license limitations below) in the documentation
and/or other materials provided with the distribution
Redistribution and use in binary form, without modification, are permitted
provided that the following conditions are met:
-
No reverse engineering, decompilation, or disassembly of this software
is permitted with respect to any software provided in binary form. -
Any redistribution and use are licensed by TI for use only with TI Devices.
-
Nothing shall obligate TI to provide you with source code for the software
licensed and provided to you in object code.
If software source code is provided to you, modification and redistribution of
the source code are permitted provided that the following conditions are met:
-
Any redistribution and use of the source code, including any resulting
derivative works, are licensed by TI for use only with TI Devices. -
Any redistribution and use of any object code compiled from the source code
and any resulting derivative works, are licensed by TI for use only with TI
Devices.
Neither the name of Texas Instruments Incorporated nor the names of its
suppliers may be used to endorse or promote products derived from this software
without specific prior written permission.
DISCLAIMER.
THIS SOFTWARE IS PROVIDED BY TI AND TI'S LICENSORS "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 TI AND TI'S LICENSORS 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.
*/
/**
- file utils_mcspi.c
- rief This file has the implementataion for UART
- version 0.0 (Aug 2016) : [PG] First version
- version 0.1 (Oct 2017) : [PG] Updated for 4 McSPI
*/
/*******************************************************************************
- INCLUDE FILES
*/
include <xdc/std.h>
include <string.h>
include <stdlib.h>
include <string.h>
include <xdc/runtime/Error.h>
include <ti/sysbios/io/GIO.h>
include <ti/sysbios/io/DEV.h>
include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
include <ti/drv/vps/include/devices/bsp_device.h>
include <ti/drv/vps/include/boards/bsp_board.h>
include <ti/csl/soc.h>
include <src/rtos/utils_common/include/utils_mcspi.h>
include <ti/drv/stw_lld/platform/irq_xbar.h>
include <stdio.h>
include <string.h>
include <xdc/std.h>
include <ti/sysbios/io/GIO.h>
include <ti/sysbios/BIOS.h>
include <xdc/runtime/Error.h>
include <xdc/runtime/System.h>
include <ti/sysbios/knl/Task.h>
include <xdc/runtime/IHeap.h>
include <ti/sysbios/heaps/HeapMem.h>
include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
include <xdc/runtime/Memory.h>
include <ti/sdo/edma3/drv/edma3_drv.h>
include <xdc/std.h>
include <stdio.h>
include <ti/sysbios/BIOS.h>
include <ti/sysbios/io/GIO.h>
include <ti/sysbios/io/IOM.h>
include <xdc/runtime/Log.h>
include <ti/sysbios/knl/Task.h>
include <ti/sysbios/heaps/HeapMem.h>
include <xdc/runtime/Error.h>
include <xdc/runtime/System.h>
include <ti/sdo/edma3/drv/edma3_drv.h>
include <ti/drv/vps/include/common/bsp_types.h>
include <ti/drv/vps/include/common/trace.h>
include <ti/drv/vps/include/common/bsp_config.h>
include <ti/drv/vps/include/common/bsp_utils.h>
include <ti/drv/vps/include/common/bsp_common.h>
include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
include <ti/drv/vps/include/platforms/bsp_platform.h>
include <ti/drv/vps/include/boards/bsp_board.h>
include <ti/drv/vps/include/devices/bsp_device.h>
include <ti/drv/bsp_lld/i2c/bsp_i2c.h>
include <ti/drv/vps/include/fvid2/fvid2.h>
include <ti/drv/vps/examples/utility/bsputils_mem.h>
include <ti/drv/vps/examples/utility/bsputils_prf.h>
include <ti/drv/vps/examples/utility/bsputils_app.h>
include <src/rtos/utils_common/include/utils_dma.h>
include <ti/csl/csl_mcspi.h>
include <ti/csl/soc.h>
include <stdio.h>
include <string.h>
include <assert.h>
include <xdc/std.h>
include <ti/sysbios/io/GIO.h>
include <ti/sysbios/BIOS.h>
include <xdc/runtime/Error.h>
include <xdc/runtime/System.h>
include <ti/sysbios/knl/Task.h>
include <ti/sysbios/knl/Semaphore.h>
include <xdc/runtime/IHeap.h>
include <ti/sysbios/heaps/HeapMem.h>
include <ti/drv/bsp_lld/mcspi/bsp_mcspi.h>
include <xdc/runtime/Memory.h>
include <ti/sdo/edma3/drv/edma3_drv.h>
include <ti/csl/soc.h>
include <ti/drv/vps/include/osal/bsp_osal.h>
include <src/rtos/utils_common/include/utils_mem.h>
define UTILS_MCSPI_NUM_MCSPI_INST (4U)
/** rief McSPI Configuration parameters */
Mcspi_Params mcspi0Prms;
Mcspi_Params mcspi1Prms;
UInt32 gIsI2cInitReq;
Int32 gMcspiOpMode;
/** rief String identifiers for the McSPI driver names */
static xdc_String gMcspiDriverNames[UTILS_MCSPI_NUM_MCSPI_INST] =
{
"/mcspi0",
"/mcspi1",
"/mcspi2",
"/mcspi3"
};
//io.c
/* ========================================================================== /
/ LOCAL FUNCTION PROTOTYPES /
/ ========================================================================== */
EDMA3_DRV_Handle edma3init(UInt32 edma3Id, EDMA3_DRV_Result *);
static void createStream(UInt32 InstNum);
static void initialize_mcspi1_buf(void);
static void initialize_mcspi2_buf(void);
static void mcspi1task(void);
static void mcspi2task(void);
static UInt32 verify_data(void);
/* ========================================================================== /
/ MACRO DEFINITONS /
/ ========================================================================== */
define BUFLEN 1024 /* Buffer size */
define BUFALIGN 128 /* Alignment of buffer for use of L2 cache */
define ITERATION_CNT 100 /* Number of Iterations */
define NUM_BUFS 3 /* Num Bufs to be issued and reclaimed */
define IOBUFLEN 32U
define NUMIOREQ ((BUFLEN / 4) + 1U)
/* ========================================================================== /
/ GLOBAL VARIABLES /
/ ========================================================================== */
extern HeapMem_Handle myHeap;
extern Int32 gMcspiOpMode;
EDMA3_DRV_Handle gEdmaHandle;
Task_Params spi2task_params;
/* Align stack memory to integer boundary. */
pragma DATA_ALIGN(gSpi2TskStack, 32)
/* Place the stack in stack section. */
pragma DATA_SECTION(gSpi2TskStack, ".bss")
/* stack for McSPI2 task */
static UInt8 gSpi2TskStack[0x8000];
/* handle to the input and output streams */
GIO_Handle mcspiHandle_mcspi1 = NULL;
GIO_Handle mcspiHandle_mcspi2 = NULL;
/* Semaphores used for syncronization */
Semaphore_Handle mcspi1Sem, mcspi2Sem, mcspiSlvSem, mcspiSlavePrimeSem;
/* Global SPI init config data structure */
Mcspi_Params spiParams;
/*
- Buffers placed in external memory are aligned on a 128 bytes boundary.
- In addition, the buffer should be of a size multiple of 128 bytes for
- the cache to work optimally.
/
/ Buffer alignement is required when working in DMA Mode */
pragma DATA_ALIGN(rxbuf0, BUFALIGN);
Ptr rxbuf0[NUM_BUFS];
/* Buffer alignement is required when working in DMA Mode */
pragma DATA_ALIGN(txbuf0, BUFALIGN);
Ptr txbuf0[NUM_BUFS];
/* Buffer alignement is required when working in DMA Mode */
pragma DATA_ALIGN(rxbuf1, BUFALIGN);
Ptr rxbuf1[NUM_BUFS];
/* Buffer alignement is required when working in DMA Mode */
pragma DATA_ALIGN(txbuf1, BUFALIGN);
Ptr txbuf1[NUM_BUFS];
/**
- rief User defined function which will initialize the McSPI. This function
-
is called when the driver for McSPI is created.
- eturn None
/
static void Utils_mcspi0UserInit(void);
static void Utils_mcspi1UserInit(void);
Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq);
void start_spi_sample(void);
/*
- rief Initializes the McSPI and adds the GIO_Device
- eturn None
/
Void Utils_mcspiInit(UInt32 mcSpiInstNum)
{
if (mcSpiInstNum < UTILS_MCSPI_NUM_MCSPI_INST)
{
/ Set the mcspi params /
switch(mcSpiInstNum)
{
case 0U: GIO_addDevice(gMcspiDriverNames[mcSpiInstNum],
(xdc_Ptr) & Mcspi_IOMFXNS,
&Utils_mcspi0UserInit,
(xdc_Int)mcSpiInstNum, (xdc_Ptr) & (mcspi0Prms));
break;
case 1U: GIO_addDevice(gMcspiDriverNames[mcSpiInstNum],
(xdc_Ptr) & Mcspi_IOMFXNS,
&Utils_mcspi1UserInit,
(xdc_Int)mcSpiInstNum, (xdc_Ptr) & (mcspi1Prms));
break;
default:
/ Should not come here */
// GIO_addDevice("/mcspi0", (xdc_Ptr) & Mcspi_IOMFXNS, &user_mcspi_init,
// 0, (xdc_Ptr) & mcspiPrms);
break;
}
}
}
Void Utils_mcspiDeinit(UInt32 mcSpiInstNum)
{
GIO_removeDevice(gMcspiDriverNames[mcSpiInstNum]);
}
void Utils_mcspiGetDevName (UInt32 mcSpiInstNum, xdc_String devName)
{
if (mcSpiInstNum < UTILS_MCSPI_NUM_MCSPI_INST)
{
strcpy(devName, gMcspiDriverNames[mcSpiInstNum]);
}
}
static void Utils_mcspi0UserInit(void)
{
Mcspi_init();
mcspi0Prms = Mcspi_PARAMS;
Vps_printf(
"Running McSPI Master Slave test.
Please Connect McSPI1 and McSPI2 pins as below.
McSPI1 CS0 to McSPI2 CS0
McSPI1 CLK to McSPI2 CLK
McSPI1 MOSI to McSPI2 MISO
McSPI1 MISO to McSPI2 MOSI
");
Vps_printf(
"And then enter the Operating mode
0 - Polled Mode
1 - Interrupt Mode
2 - DMA Interrupt mode
$>");
// scanf("%d", &gMcspiOpMode);
gMcspiOpMode =0;
if (gMcspiOpMode == 0)
{
mcspi0Prms.opMode = MCSPI_OPMODE_POLLED;
gMcspiOpMode = MCSPI_OPMODE_POLLED;
}
else if (gMcspiOpMode == 1)
{
mcspi0Prms.opMode = MCSPI_OPMODE_INTERRUPT;
gMcspiOpMode = MCSPI_OPMODE_INTERRUPT;
}
else if (gMcspiOpMode == 2)
{
mcspi0Prms.opMode = MCSPI_OPMODE_DMAINTERRUPT;
gMcspiOpMode = MCSPI_OPMODE_DMAINTERRUPT;
}
else
{
mcspi0Prms.opMode = MCSPI_OPMODE_POLLED;
gMcspiOpMode = MCSPI_OPMODE_POLLED;
}
/* Instance number is 0 for McSPI1 */
mcspi0Prms.instNum = 0;
mcspi0Prms.hwiNumber = 7;
mcspi0Prms.enableCache = (UInt32) TRUE;
mcspi0Prms.edma3EventQueue = 0;
mcspi0Prms.enableErrIntr = (UInt32) FALSE;
mcspi0Prms.spiHWCfgData.masterOrSlave = MCSPI_COMMMODE_MASTER;
mcspi0Prms.spiHWCfgData.singleOrMultiChEnable = MCSPI_SINGLE_CHANNEL;
mcspi0Prms.spiHWCfgData.pinOpModes = MCSPI_PINOPMODE_4PIN;
mcspi0Prms.spiHWCfgData.fifoRxTrigLvl = 16;
mcspi0Prms.spiHWCfgData.fifoTxTrigLvl = 16;
mcspi0Prms.spiHWCfgData.configChfmt[0].charLength = MCSPI_LEN_32BIT;
mcspi0Prms.spiHWCfgData.configChfmt[0].multiWordAccessEnable =
(UInt32) FALSE;
mcspi0Prms.spiHWCfgData.configChfmt[0].spiChipSelectEnablePol =
(UInt32) FALSE;
mcspi0Prms.spiHWCfgData.configChfmt[0].clockMode = MCSPI_MODE0;
mcspi0Prms.spiHWCfgData.configChfmt[0].clockRatioExtension = 0;
mcspi0Prms.spiHWCfgData.configChfmt[0].spiWordInitDelay = MCSPI_NO_DELAY;
mcspi0Prms.spiHWCfgData.configChfmt[0].trasmitReceiveMode =
MCSPI_BOTH_RXTX;
mcspi0Prms.spiHWCfgData.configChfmt[0].granularityEnable = (UInt32) TRUE;
mcspi0Prms.spiHWCfgData.configChfmt[0].busFreq = 1000000;
mcspi0Prms.spiHWCfgData.configChfmt[0].spienHighPolarity = (UInt32) FALSE;
mcspi0Prms.spiHWCfgData.configChfmt[0].slaveModeChipSelect = MCSPI_SPIEN_0;
mcspi0Prms.spiHWCfgData.configChfmt[0].spiDat0Dir = MCSPI_IN;
mcspi0Prms.spiHWCfgData.configChfmt[0].spiDat1Dir = MCSPI_OUT;
if (MCSPI_OPMODE_POLLED == mcspi0Prms.opMode)
{
Vps_printf("
Mcspi is configured in polled mode
");
}
else if (MCSPI_OPMODE_INTERRUPT == mcspi0Prms.opMode)
{
Vps_printf("
Mcspi is configured in interrupt mode
");
}
else if (MCSPI_OPMODE_DMAINTERRUPT == mcspi0Prms.opMode)
{
Vps_printf("
Mcspi is configured in dma mode
");
}
else
{
Vps_printf("
Error: unknown mode of operation!!!!!!!!!!
");
}
}
static void Utils_mcspi1UserInit(void)
{
mcspi1Prms = Mcspi_PARAMS;
/* Operation Mode of McSPI1 and McSPI2 instance is same /
mcspi1Prms.opMode = mcspi0Prms.opMode;
/ Instance number is 1 for McSPI2 */
mcspi1Prms.instNum = 1;
mcspi1Prms.hwiNumber = 7;
mcspi1Prms.enableCache = (UInt32) TRUE;
mcspi1Prms.edma3EventQueue = 0;
mcspi1Prms.enableErrIntr = (UInt32) FALSE;
mcspi1Prms.spiHWCfgData.masterOrSlave = MCSPI_COMMMODE_SLAVE;
mcspi1Prms.spiHWCfgData.singleOrMultiChEnable = MCSPI_SINGLE_CHANNEL;
mcspi1Prms.spiHWCfgData.pinOpModes = MCSPI_PINOPMODE_4PIN;
mcspi1Prms.spiHWCfgData.fifoRxTrigLvl = 16;
mcspi1Prms.spiHWCfgData.fifoTxTrigLvl = 16;
mcspi1Prms.spiHWCfgData.configChfmt[0].charLength = MCSPI_LEN_32BIT;
mcspi1Prms.spiHWCfgData.configChfmt[0].multiWordAccessEnable =
(UInt32) FALSE;
mcspi1Prms.spiHWCfgData.configChfmt[0].spiChipSelectEnablePol =
(UInt32) FALSE;
mcspi1Prms.spiHWCfgData.configChfmt[0].clockMode = MCSPI_MODE0;
mcspi1Prms.spiHWCfgData.configChfmt[0].clockRatioExtension = 0;
mcspi1Prms.spiHWCfgData.configChfmt[0].spiWordInitDelay = MCSPI_NO_DELAY;
mcspi1Prms.spiHWCfgData.configChfmt[0].trasmitReceiveMode =
MCSPI_BOTH_RXTX;
mcspi1Prms.spiHWCfgData.configChfmt[0].granularityEnable = (UInt32) TRUE;
mcspi1Prms.spiHWCfgData.configChfmt[0].busFreq = 1000000;
mcspi1Prms.spiHWCfgData.configChfmt[0].spienHighPolarity = (UInt32) FALSE;
mcspi1Prms.spiHWCfgData.configChfmt[0].slaveModeChipSelect = MCSPI_SPIEN_0;
mcspi1Prms.spiHWCfgData.configChfmt[0].spiDat0Dir = MCSPI_IN;
mcspi1Prms.spiHWCfgData.configChfmt[0].spiDat1Dir = MCSPI_OUT;
}
void spiSampleTask(void)
{
Int32 retVal = FVID2_SOK;
// Bsp_PlatformInitParams platInitPrms;
/* isPinMuxSettingReq parameter will be initialised to TRUE */
// BspPlatformInitParams_init(&platInitPrms);
// platInitPrms.isAllMcSPIInitReq = TRUE;
// platInitPrms.isPinMuxSettingReq = TRUE;
/* Initialize pinmux and evm related configurations */
// Bsp_platformInit(&platInitPrms);
/* System init */
gIsI2cInitReq = TRUE;
retVal = App_mcspiDefaultInit(gIsI2cInitReq);
if (retVal != FVID2_SOK)
{
Vps_printf("Error: : System Init Failed!!!
");
}
/* Set the pin Mux */
Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0,
BSP_BOARD_MODE_DEFAULT);
Bsp_boardSetPinMux(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_1,
BSP_BOARD_MODE_DEFAULT);
/* Set the board muxes */
Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_0);
Bsp_boardSelectDevice(BSP_DRV_ID_MCSPI, BSP_DEVICE_MCSPI_INST_ID_1);
if defined (SOC_TDA3XX)
/* Enable PRCM for the McSPI */
PlatformMCSPI1PrcmEnable();
PlatformMCSPI2PrcmEnable();
endif
/* call the function for the SPI application test */
start_spi_sample();
// App_mcspiDefaultDeInit(gIsI2cInitReq);
/* Start the Heart Beat Print */
// tskHeartBeat();
return;
}
Int32 App_mcspiDefaultInit(UInt32 isI2cInitReq)
{
Int32 retVal = BSP_SOK;
//UInt32 instCnt;
Bsp_CommonInitParams commonInitPrms;
Bsp_BoardInitParams boardInitPrms;
Bsp_PlatformInitParams platInitPrms;
//Bsp_DeviceInitParams deviceInitPrms;
//lld_hsi2c_initParam_t i2cInitParams[BSP_DEVICE_I2C_INST_ID_MAX];
//const Bsp_BoardI2cData *i2cData;
//Bsp_BoardI2cInstData *i2cInstData;
BspCommonInitParams_init(&commonInitPrms);
retVal += Bsp_commonInit(&commonInitPrms);
if (BSP_SOK != retVal)
{
GT_0trace(BspAppTrace, GT_ERR, "Error: BSP Common Init failed!!
");
}
BspBoardInitParams_init(&boardInitPrms);
/* Override board detection if I2C is disabled */
if (((Bool) TRUE) != ((Bool) isI2cInitReq))
{
boardInitPrms.boardId = BSP_BOARD_UNKNOWN;
boardInitPrms.baseBoardRev = BSP_BOARD_REV_UNKNOWN;
boardInitPrms.dcBoardRev = BSP_BOARD_REV_UNKNOWN;
}
retVal += Bsp_boardInit(&boardInitPrms);
if (BSP_SOK != retVal)
{
GT_0trace(BspAppTrace, GT_ERR, "Error: Board Init failed!!
");
}
BspPlatformInitParams_init(&platInitPrms);
retVal += Bsp_platformInit(&platInitPrms);
if (BSP_SOK != retVal)
{
GT_0trace(BspAppTrace, GT_ERR, "Error: Platform Init failed!!
");
}
retVal += Fvid2_init(NULL);
if (BSP_SOK != retVal)
{
GT_0trace(BspAppTrace, GT_ERR, "Error: FVID2 Init failed!!
");
}
/* Override I2C init for non-EVM builds */
if (BSP_PLATFORM_ID_EVM != Bsp_platformGetId())
{
isI2cInitReq = FALSE;
}
/* if (((Bool) TRUE) == ((Bool) isI2cInitReq))
{
i2cData = Bsp_boardGetI2cData();
GT_assert(BspAppTrace, (NULL != i2cData));
GT_assert(BspAppTrace,
(i2cData->numInst <= BSP_DEVICE_I2C_INST_ID_MAX));
GT_assert(BspAppTrace, (NULL != i2cData->instData));
for (instCnt = 0U; instCnt < i2cData->numInst; instCnt++)
{
i2cInstData = &i2cData->instData[instCnt];
GT_assert(BspAppTrace,
(i2cInstData->instId < BSP_DEVICE_I2C_INST_ID_MAX));
i2cInitParams[instCnt].opMode = HSI2C_OPMODE_INTERRUPT;
i2cInitParams[instCnt].isMasterMode = TRUE;
i2cInitParams[instCnt].is10BitAddr = FALSE;
i2cInitParams[instCnt].i2cBusFreq =
(lld_i2c_busspeed) i2cInstData->busClkKHz;
i2cInitParams[instCnt].i2cIntNum = i2cInstData->intNum;
i2cInitParams[instCnt].i2cOwnAddr = 0xCC;
gI2cDevInitParams[instCnt].initParams = &i2cInitParams[instCnt];
gI2cDevInitParams[instCnt].hsi2c_sem =
BspOsal_semCreate((Int32) 1, (Bool) TRUE);
gI2cDevInitParams[instCnt].instId = i2cInstData->instId;
}
if (i2cData->numInst > 0)
{
retVal = I2c_GlobalInit(i2cData->numInst, &gI2cDevInitParams[0U]);
if (BSP_SOK != retVal)
{
GT_0trace(BspAppTrace, GT_ERR, "Error: I2C Init failed!!
");
}
}
BspDeviceInitParams_init(&deviceInitPrms);
deviceInitPrms.isI2cProbingReq = FALSE;
retVal += Bsp_deviceInit(&deviceInitPrms);
if (BSP_SOK != retVal)
{
GT_0trace(BspAppTrace, GT_ERR, "Error: Device Init failed!!
");
}
}*/
// retVal += BspUtils_memInit();
// if (BSP_SOK != retVal)
// {
// GT_0trace(BspAppTrace, GT_ERR, "Error: App MEM Utils Init failed!!
");
// }
//
// retVal += BspUtils_prfInit();
// if (BSP_SOK != retVal)
// {
// GT_0trace(BspAppTrace, GT_ERR, "Error: App PRF Utils Init failed!!
");
// }
retVal += BspUtils_appInit();
if (BSP_SOK != retVal)
{
GT_0trace(BspAppTrace, GT_ERR, "Error: App Utils Init failed!!
");
}
/* Print BSP version string and platform info*/
GT_0trace(BspAppTrace, GT_INFO, "
");
GT_2trace(BspAppTrace, GT_INFO,
" Build time : [%s %s]
", __TIME__, __DATE__);
GT_1trace(BspAppTrace, GT_INFO,
" BSP Version : [%s]
", Bsp_getVersionString());
Bsp_platformPrintInfo();
Bsp_boardPrintInfo();
GT_0trace(BspAppTrace, GT_INFO, "
");
return (retVal);
}
//io.c
/* ========================================================================== /
/ FUNCTION DEFINITIONS /
/ ========================================================================== */
static void createStream(UInt32 InstNum)
{
GIO_Params ioParams;
Mcspi_ChanParams chanParams;
Error_Block eb;
Error_init(&eb);
/*
* Initialize channel attributes.
*/
GIO_Params_init(&ioParams);
/* initialze chanParams */
Mcspi_ChanParams_init(&chanParams);
/* update the edma Handle */
chanParams.hEdma = gEdmaHandle;
chanParams.chipSelTimeControl = MCSPI_CLK_CYCLE0;
chanParams.fifoEnable = (UInt32) TRUE;
chanParams.spiChipSelectHold = (UInt32) TRUE;
chanParams.chanNum = 0;
/* If cross bar events are being used then make isCrossBarIntEn = TRUE and
* choose appropriate interrupt number to be mapped (assign it to
* intNumToBeMapped)
*/
/* Cross bar evt disabled */
chanParams.crossBarEvtParam.isCrossBarIntEn = (UInt32) FALSE;
chanParams.crossBarEvtParam.intNumToBeMapped = 0xFF; /* Invalid number */
ioParams.chanParams = (Ptr) & chanParams;
ioParams.model = GIO_Model_ISSUERECLAIM;
ioParams.numPackets = NUM_BUFS + 1;
if (InstNum == 0U)
{
/* Pass the DMA channels to be used for SPI DMA mode. */
chanParams.useAppSpecifiedDmaEvtNumbers = TRUE;
chanParams.rxDmaEventNumber = (UInt32) CSL_EDMA3_CHA0_MCSPI0_RX;
chanParams.txDmaEventNumber = (UInt32) CSL_EDMA3_CHA0_MCSPI0_TX;
mcspiHandle_mcspi1 = GIO_create("/mcspi0", GIO_INOUT, &ioParams, &eb);
if (mcspiHandle_mcspi1 == NULL)
{
Vps_printf("
Create input stream FAILED.
");
BIOS_exit(0);
}
}
else
{
mcspiHandle_mcspi2 = GIO_create("/mcspi1", GIO_INOUT, &ioParams, &eb);
if (mcspiHandle_mcspi2 == NULL)
{
Vps_printf("
Create input stream FAILED.
");
BIOS_exit(0);
}
}
}
static void initialize_mcspi1_buf(void)
{
// Error_Block eb;
Int32 count = 0;
// IHeap_Handle iheap;
UInt32 tempCount = 0;
Utils_HeapId heapId;
heapId = UTILS_HEAPID_DDR_CACHED_LOCAL;
// heapId = UTILS_HEAPID_DDR_CACHED_SR;
// iheap = HeapMem_Handle_to_xdc_runtime_IHeap(myHeap);
// Error_init(&eb);
/* Allocate buffers for the GIO buffer exchanges for McSPI1 */
for (count = 0; count < (NUM_BUFS); count++)
{
// rxbuf0[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
rxbuf0[count] = (Ptr)Utils_memAlloc(
heapId,
BUFLEN,
BUFALIGN
);
if (NULL == rxbuf0[count])
{
Vps_printf("
MEM_calloc failed.
");
}
txbuf0[count] = (Ptr)Utils_memAlloc(
heapId,
BUFLEN,
BUFALIGN
);
if (NULL == txbuf0[count])
{
Vps_printf("
MEM_calloc failed.
");
}
}
/* Fill the buffers with known data and transmit the same and check if the*
* same pattern is received at McSPI2 Buffers */
for (count = 0; count < (NUM_BUFS); count++)
{
for (tempCount = 0; tempCount < BUFLEN; tempCount++)
{
((Uint8 *) txbuf0[count])[tempCount] = (tempCount % 0x100);
}
}
/* Cache writeback after buffer initialization with CPU access */
BspOsal_cacheWbInvAll();
}
static void initialize_mcspi2_buf(void)
{
// Error_Block eb;
Int32 count = 0;
// IHeap_Handle iheap;
UInt32 tempCount = 0;
Utils_HeapId heapId;
heapId = UTILS_HEAPID_DDR_CACHED_LOCAL;
// heapId = UTILS_HEAPID_DDR_CACHED_SR;
// iheap = HeapMem_Handle_to_xdc_runtime_IHeap(myHeap);
// Error_init(&eb);
/* Allocate buffers for the GIO buffer exchanges for McSPI2 */
for (count = 0; count < (NUM_BUFS); count++)
{
// rxbuf1[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
rxbuf1[count] = (Ptr)Utils_memAlloc(
heapId,
BUFLEN,
BUFALIGN
);
if (NULL == rxbuf1[count])
{
Vps_printf("
MEM_calloc failed.
");
}
// txbuf1[count] = (Ptr) Memory_calloc(iheap, BUFLEN, BUFALIGN, &eb);
txbuf1[count] = (Ptr)Utils_memAlloc(
heapId,
BUFLEN,
BUFALIGN
);
if (NULL == txbuf1[count])
{
Vps_printf("
MEM_calloc failed.
");
}
}
/* Fill the buffers with known data and transmit the same and check if the*
* same pattern is received at McSPI1 Buffers */
for (count = 0; count < (NUM_BUFS); count++)
{
for (tempCount = 0; tempCount < BUFLEN; tempCount++)
{
((Uint8 *) txbuf1[count])[tempCount] = (tempCount % 0x100);
}
}
/* Cache writeback after buffer initialization with CPU access */
BspOsal_cacheWbInvAll();
}
static void mcspi1task(void)
{
UInt32 size = 0;
UInt32 count = 0;
UInt32 i, iterations = 0;
Int status = IOM_COMPLETED;
UInt32 tempBuffAddr;
Mcspi_DataParam issueDataparam[NUM_BUFS][NUMIOREQ];
Mcspi_DataParam reclaimDataparam[NUM_BUFS];
/* Call createStream function to create I/O streams */
createStream(0U);
initialize_mcspi1_buf();
for (count = 0; count < NUM_BUFS; count++)
{
/* In case of multiple bufs make sure that previous reclaim happened at
* McSPI2 */
Semaphore_pend(mcspi2Sem, BIOS_WAIT_FOREVER);
/* For Polled Mode transfer driver cannot synchronize between transfers
* on McSPI1 and McSPI2. McSPI2 (Slave) Tx should be having valid data
* before writing to McSPI1 (Master) Tx to ensure data integrity. In
* case of Interrupt and DMA mode driver task need not do the
* synchronization, hence single issue is done for whole buffer */
if (gMcspiOpMode == MCSPI_OPMODE_POLLED)
{
size = 4;
iterations = BUFLEN / 4U;
}
else
{
size = IOBUFLEN;
iterations = BUFLEN / IOBUFLEN;
}
if (gMcspiOpMode == MCSPI_OPMODE_INTERRUPT)
{
/* Wait for the slave iop priming */
Semaphore_pend(mcspiSlavePrimeSem, BIOS_WAIT_FOREVER);
}
for (i = 0; i < iterations; i++)
{
if (gMcspiOpMode != MCSPI_OPMODE_INTERRUPT)
{
/* pend of Sem to make sure slave Tx is written before Master */
Semaphore_pend(mcspiSlvSem, BIOS_WAIT_FOREVER);
}
issueDataparam[count][i].bufLen = size;
tempBuffAddr = (UInt32) rxbuf0[count];
tempBuffAddr += (i * issueDataparam[count][i].bufLen);
issueDataparam[count][i].inBuffer = (UInt8 *) (tempBuffAddr);
tempBuffAddr = (UInt32) txbuf0[count];
tempBuffAddr += (i * issueDataparam[count][i].bufLen);
issueDataparam[count][i].outBuffer = (UInt8 *) (tempBuffAddr);
/* Issue the first & second empty buffers to the input stream */
status =
GIO_issue(mcspiHandle_mcspi1, &issueDataparam[count][i], size,
NULL);
if (status != IOM_PENDING && status != IOM_COMPLETED)
{
Vps_printf("
Failed to issue empty buffer to stream
");
}
/* Reclaim is done after every issue and buffers are not primed. If
* the buffers are primed next transfer is initialized as soon as
* the first one is completed. We wont be able to ensure transfer
* initializaton on Slave before master for second buffer */
status =
GIO_reclaim(mcspiHandle_mcspi1, (Ptr *) &reclaimDataparam, NULL,
NULL);
if (IOM_COMPLETED != status)
{
Vps_printf("Iteration %d
", count);
Vps_printf(
"Error reclaiming empty buffer from the streams %x"
" error = 0x%d
",
((Uint8) (reclaimDataparam->outBuffer[count])),
status);
break;
}
if (gMcspiOpMode == MCSPI_OPMODE_INTERRUPT)
{
Task_yield();
}
}
if (gMcspiOpMode == MCSPI_OPMODE_INTERRUPT)
{
Task_yield();
}
/* Post Sem for telling reclaim done on McSPI1 */
Semaphore_post(mcspi1Sem);
}
}
static void mcspi2task(void)
{
UInt32 size = 0;
UInt32 count = 0;
UInt32 i, iterations = 0;
Int status = IOM_COMPLETED;
UInt32 tempBuffAddr;
Mcspi_DataParam issueDataparam[NUM_BUFS][NUMIOREQ];
Mcspi_DataParam reclaimDataparam[NUM_BUFS];
/* Call createStream function to create I/O streams */
createStream(1U);
initialize_mcspi2_buf();
for (count = 0; count < NUM_BUFS; count++)
{
/* In case of multiple bufs make sure that previous reclaim happened at
* McSPI1 */
Semaphore_pend(mcspi1Sem, BIOS_WAIT_FOREVER);
if (gMcspiOpMode == MCSPI_OPMODE_POLLED)
{
size = 4;
iterations = BUFLEN / 4U;
}
else
{
size = IOBUFLEN;
iterations = BUFLEN / IOBUFLEN;
}
if (gMcspiOpMode == MCSPI_OPMODE_INTERRUPT)
{
/* In case of Interrupt mode prime one iop */
tempBuffAddr = (UInt32) rxbuf1[count];
issueDataparam[count][0].inBuffer = (UInt8 *) (tempBuffAddr);
tempBuffAddr = (UInt32) txbuf1[count];
issueDataparam[count][0].outBuffer = (UInt8 *) (tempBuffAddr);
issueDataparam[count][0].bufLen = size;
status =
GIO_issue(mcspiHandle_mcspi2, &issueDataparam[count][0], size,
NULL);
if (status != IOM_PENDING && status != IOM_COMPLETED)
{
Vps_printf("
Failed to issue empty buffer to stream
");
}
/* Initialize loopcount to 1 as one issue is already done. */
i = 1;
/* Post sem to indicate that priming in slave is done */
Semaphore_post(mcspiSlavePrimeSem);
}
else
{
i = 0;
}
for (; i < iterations; i++)
{
issueDataparam[count][i].bufLen = size;
tempBuffAddr = (UInt32) rxbuf1[count];
tempBuffAddr += (i * issueDataparam[count][i].bufLen);
issueDataparam[count][i].inBuffer = (UInt8 *) (tempBuffAddr);
tempBuffAddr = (UInt32) txbuf1[count];
tempBuffAddr += (i * issueDataparam[count][i].bufLen);
issueDataparam[count][i].outBuffer = (UInt8 *) (tempBuffAddr);
/* Post Sem for Issue of Slave transfer. Post is done before
* GIO_issue as in case of polled mode GIO_issue is blocking and
* needs McSPI1 task to run, to go for completion but task switch
* wont happen till First Tx is written to slave */
if (gMcspiOpMode != MCSPI_OPMODE_INTERRUPT)
{
Semaphore_post(mcspiSlvSem);
}
/* Issue the first & second empty buffers to the input stream */
status =
GIO_issue(mcspiHandle_mcspi2, &issueDataparam[count][i], size,
NULL);
if (status != IOM_PENDING && status != IOM_COMPLETED)
{
Vps_printf("
Failed to issue empty buffer to stream
");
}
/* Reclaim is done after every issue and buffers are not primed. If
* *the buffers are primed next transfer is initialized as soon as
* the first one is completed. We wont be able to ensure transfer
*initializaton on Slave before master for second buffer */
status =
GIO_reclaim(mcspiHandle_mcspi2, (Ptr *) &reclaimDataparam, NULL,
NULL);
if (IOM_COMPLETED != status)
{
Vps_printf("Iteration %d
", count);
Vps_printf(
"Error reclaiming empty buffer from the streams %x"
" error = 0x%d
",
((Uint8) (reclaimDataparam->outBuffer[count])),
status);
break;
}
}
if (gMcspiOpMode == MCSPI_OPMODE_INTERRUPT)
{
/* Reclaim the last buffer in case of interrupt mode */
status =
GIO_reclaim(mcspiHandle_mcspi2, (Ptr *) &reclaimDataparam, NULL,
NULL);
}
/* Post Sem for telling reclaim done on McSPI2 */
Semaphore_post(mcspi2Sem);
}
}
static UInt32 verify_data(void)
{
volatile Int32 count, tempCount;
UInt8 *srcBuff0, *dstBuff0;
UInt8 *srcBuff1, *dstBuff1;
UInt32 retVal = 0U;
for (count = 0U; count < NUM_BUFS; count++)
{
srcBuff0 = rxbuf0[count];
dstBuff0 = txbuf0[count];
srcBuff1 = rxbuf1[count];
dstBuff1 = txbuf1[count];
for (tempCount = 0; tempCount < BUFLEN; tempCount++)
{
if (srcBuff0[tempCount] != dstBuff1[tempCount])
{
Vps_printf(
"Error matching master receive data at location %d
",
tempCount);
retVal = 1U;
break;
}
}
for (tempCount = 0; tempCount < BUFLEN; tempCount++)
{
if (srcBuff1[tempCount] != dstBuff0[tempCount])
{
Vps_printf(
"Error matching slave receive data at location %d
",
tempCount);
retVal = 1U;
break;
}
}
}
return retVal;
}
void start_spi_sample(void)
{
Semaphore_Params semParams;
EDMA3_DRV_Result edmaResult = 0;
UInt32 initVal = 1U;
gEdmaHandle = edma3init(0, &edmaResult);
if (edmaResult != EDMA3_DRV_SOK)
{
/* Report EDMA Error */
Vps_printf("
EDMA driver initialization FAIL
");
}
else
{
Vps_printf("
EDMA driver initialization PASS.
");
}
/* Initialize Semaphores used for Synchronization */
Semaphore_Params_init(&semParams);
mcspi1Sem = Semaphore_create(initVal, &semParams, NULL);
mcspi2Sem = Semaphore_create(initVal, &semParams, NULL);
mcspiSlvSem = Semaphore_create(0U, &semParams, NULL);
mcspiSlavePrimeSem = Semaphore_create(0U, &semParams, NULL);
assert(mcspi1Sem != NULL);
assert(mcspi2Sem != NULL);
assert(mcspiSlvSem != NULL);
assert(mcspiSlavePrimeSem != NULL);
Task_Params_init(&spi2task_params);
spi2task_params.stack = gSpi2TskStack;
spi2task_params.stackSize = sizeof (gSpi2TskStack);
/* Create aniother task for McSPI2 transfer */
Task_create((Task_FuncPtr) mcspi2task, &spi2task_params, NULL);
/* Continue McSPI1 transfer in current task */
mcspi1task();
/* McSPI1 reclaim is completed, Wait till Buffer reclaim is completed on
* McSPI2 */
Semaphore_pend(mcspi2Sem, BIOS_WAIT_FOREVER);
/* Cache writeback before buffer verification. */
BspOsal_cacheWbInvAll();
if (verify_data() == 0)
{
Vps_printf("Data varification passed
");
Vps_printf("McSPI Master Slave application Passed
");
}
else
{
Vps_printf("McSPI Master Slave application Failed
");
}
}