This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
工程师你好:
我目前采用6678与Xilinx Virtex6通过SRIO接口通信,由于设计要求需要进行如下操作:
由FPGA 做SRIO主动发起方,DSP作为目的器件。由FPGA发起Nread操作,对DSP外挂的DDR3进行数据读取。
根据我的理解,DSP由于不需要进行SRIO的操作,所以只对DSP进行SRIO的初始化,使SRIO工作即可,DDR的所有地址对FPGA是透明可见的,DSP不需要再有额外的SRIO操作。
但是根据测试,出现了以下现象:
FPGA向DSP读取32个256字节,也就是回读时会产生32个SRIO包,产生的源事物ID也为32个,但是读回来的数据当中丢失了一个数据包,事物ID缺少了一个,并且多次测试结果都是一样。
请问工程师,当外部器件对DSP通过SRIO发起读操作的时候,DSP需要哪些配置和操作,我上面的理解是否正确,SRIO丢失数据包可能的原因是否与DSP有关系???DSP的SRIO代码是论坛提供的源码修改的
你的理解是正确的。对于FPGA读取DSP的内容,DSP只需要将SRIO完成初始化,也就是保证端口状态是OK就行。
你可以把问题描述再清楚些,别如32个256byte地址连续不,丢了哪一个,你如何发送的Nread,读出来的数据对不对,等等。
有如下建议请参考:
1)检查DSP的错误侦测寄存器,查看是否有错误发生;
2)如果FPGA是通过switch连接的,也要查看switch的状态是否ok
3)改为带Response的Read方式试试
谢谢你的回复,我的问题具体现象如下:
发送32个256Byte,总是第26个数据包缺少,事物ID就缺少这一个,从FPGA的Chipscope可以看到这个现象,但是当我发送24个32Byte的时候,就不会丢失;
我发送的Nread请求是由FPGA产生的,具体的解决方案是Xilinx 的RapidIO IP core,回读的数据是正确的。
板卡FPGA与DSP之间是之间直接相连的。
你好,能把你的6678的srio与fpga通信的程序发我一下吗,我也在做这个,看了一下keystone的srio芯片手册,基本结构懂了,但是还有很多细节不知道,想参考一下您的代码,谢谢了,我的邮箱是maguodong12345@126.com
/** * @file loopbackDioIsr.c * * @brief * This is an example application which shows how DIO transfer * completion interrupts can be registered and serviced. * * \par * NOTE: * (C) Copyright 2011 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. * * \par */ #include <xdc/std.h> #include <string.h> #include <c6x.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/heaps/HeapBuf.h> #include <ti/sysbios/heaps/HeapMem.h> #include <ti/sysbios/family/c64p/Hwi.h> #include <ti/sysbios/family/c64p/EventCombiner.h> #include <ti/sysbios/family/c66/tci66xx/CpIntc.h> /* IPC includes */ #include <ti/ipc/GateMP.h> #include <ti/ipc/Ipc.h> #include <ti/ipc/ListMP.h> #include <ti/ipc/SharedRegion.h> #include <ti/ipc/MultiProc.h> #include <xdc/cfg/global.h> /* SRIO Driver Include File. */ #include <ti/drv/srio/srio_drv.h> #include <ti/drv/srio/srio_osal.h> /* CPPI/QMSS Include Files. */ #include <ti/drv/cppi/cppi_drv.h> #include <ti/drv/qmss/qmss_drv.h> #include <ti/drv/qmss/qmss_firmware.h> /* CSL Chip Functional Layer */ #include <ti/csl/csl_chip.h> /* CSL Cache Functional Layer */ #include <ti/csl/csl_cacheAux.h> /* PSC CSL Include Files */ #include <ti/csl/csl_psc.h> #include <ti/csl/csl_pscAux.h> /* CSL SRIO Functional Layer */ #include <ti/csl/csl_srio.h> #include <ti/csl/csl_srioAux.h> /* CSL CPINTC Include Files. */ #include<ti/csl/csl_cpIntc.h> /********************************************************************** ************************** LOCAL Definitions ************************* **********************************************************************/ /* This is the Number of host descriptors which are available & configured * in the memory region for this example. */ #define NUM_HOST_DESC 128 /* This is the size of each descriptor. */ #define SIZE_HOST_DESC 48 /* MTU of the SRIO Driver. We are currently operating @ MTU of 256 bytes. */ #define SRIO_MAX_MTU 256 /* This is the size of the data buffer which is used for DIO Sockets. */ #define SIZE_DIO_PACKET 128 /* Defines the core number responsible for system initialization. */ #define CORE_SYS_INIT 0 /* Defines number of DIO sockets used in this example */ #define SRIO_DIO_LSU_ISR_NUM_SOCKETS 3 /* Defines number of transfers done by DIO sockets in this example */ #define SRIO_DIO_LSU_ISR_NUM_TRANSFERS 3 /* ISR timeout value (in cycles) used in this example */ #define SRIO_DIO_LSU_ISR_TIMEOUT 50000 #define DST ((Uint8 *)0x100000) /********************************************************************** ************************** Global Variables ************************** **********************************************************************/ /* Memory allocated for the descriptors. This is 16 bit aligned. */ #pragma DATA_ALIGN (host_region, 16) Uint8 host_region[NUM_HOST_DESC * SIZE_HOST_DESC]; /* Memory used for the accumulator list. */ #pragma DATA_ALIGN (gHiPriAccumList, 16) UInt32 gHiPriAccumList[64]; /* Global SRIO and QMSS Configuration */ Qmss_InitCfg qmssInitConfig; /* Global Varialble which keeps track of the core number executing the * application. */ UInt32 coreNum = 0xFFFF; /* Shared Memory Variable to ensure synchronizing SRIO initialization * with all the other cores. */ #pragma DATA_ALIGN (isSRIOInitialized, 128) #pragma DATA_SECTION (isSRIOInitialized, ".srioSharedMem"); volatile Uint32 isSRIOInitialized = 0; Srio_DrvHandle hAppManagedSrioDrv; Srio_DrvHandle hDrvManagedSrioDrv; CSL_SrioHandle hSrioCSL; /* These are the device identifiers used in the Example Application */ const uint32_t DEVICE_ID1_16BIT = 0xBEEF; const uint32_t DEVICE_ID1_8BIT = 0xAB; const uint32_t DEVICE_ID2_16BIT = 0x4560; const uint32_t DEVICE_ID2_8BIT = 0xCD; const uint32_t DEVICE_ID3_16BIT = 0x1234; const uint32_t DEVICE_ID3_8BIT = 0x12; //const uint32_t DEVICE_ID4_16BIT = 0x5678; const uint32_t DEVICE_ID4_16BIT = 0xABFF; const uint32_t DEVICE_ID4_8BIT = 0x56; /* Array containing SRIO socket handles */ Srio_SockHandle srioSocket[SRIO_DIO_LSU_ISR_NUM_SOCKETS]; /* Source and Destination Data Buffers (payload buffers) */ UInt8* srcDataBuffer[SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS]; UInt8* dstDataBuffer[SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS]; /* Global debug variable to track number of ISRs raised */ volatile UInt32 srioDbgDioIsrCnt = 0; /* Global variable to indicate completion of ISR processing */ volatile UInt32 srioLsuIsrServiced = 0; /* Global variables to count good and bad transfers */ volatile UInt32 srioDioLsuGoodTransfers = 0; volatile UInt32 srioDioLsuBadTransfers = 0; /********************************************************************** ************************* Extern Definitions ************************* **********************************************************************/ extern UInt32 malloc_counter; extern UInt32 free_counter; extern int32_t SrioDevice_init (void); /* QMSS device specific configuration */ extern Qmss_GlobalConfigParams qmssGblCfgParams; /* CPPI device specific configuration */ extern Cppi_GlobalConfigParams cppiGblCfgParams; /* OSAL Data Buffer Memory Initialization. */ extern int32_t Osal_dataBufferInitMemory(uint32_t dataBufferSize); /********************************************************************** ************************ SRIO EXAMPLE FUNCTIONS ********************** **********************************************************************/ /** * @b Description * @n * Utility function which converts a local address to global. * * @param[in] addr * Local address to be converted * * @retval * Global Address */ static UInt32 l2_global_address (Uint32 addr) { UInt32 corenum; /* Get the core number. */ corenum = CSL_chipReadReg(CSL_CHIP_DNUM); /* Compute the global address. */ return (addr + (0x10000000 + (corenum*0x1000000))); } /** * @b Description * @n * Utility function that is required by the IPC module to set the proc Id. * The proc Id is set via this function instead of hard coding it in the .cfg file * * @retval * Not Applicable. */ Void myStartupFxn (Void) { MultiProc_setLocalId (CSL_chipReadReg (CSL_CHIP_DNUM)); } /** * @b Description * @n * This function enables the power/clock domains for SRIO. * * @retval * Not Applicable. */ static Int32 enable_srio (void) { #ifndef SIMULATOR_SUPPORT /* SRIO power domain is turned OFF by default. It needs to be turned on before doing any * SRIO device register access. This not required for the simulator. */ /* Set SRIO Power domain to ON */ CSL_PSC_enablePowerDomain (CSL_PSC_PD_SRIO); /* Enable the clocks too for SRIO */ CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SRIO, PSC_MODSTATE_ENABLE); /* Start the state transition */ CSL_PSC_startStateTransition (CSL_PSC_PD_SRIO); /* Wait until the state transition process is completed. */ while (!CSL_PSC_isStateTransitionDone (CSL_PSC_PD_SRIO)); /* Return SRIO PSC status */ if ((CSL_PSC_getPowerDomainState(CSL_PSC_PD_SRIO) == PSC_PDSTATE_ON) && (CSL_PSC_getModuleState (CSL_PSC_LPSC_SRIO) == PSC_MODSTATE_ENABLE)) { /* SRIO ON. Ready for use */ return 0; } else { /* SRIO Power on failed. Return error */ return -1; } #else /* PSC is not supported on simulator. Return success always */ return 0; #endif } /** * @b Description * @n * This function is application registered SRIO DIO LSU interrupt * handler (ISR) which is used to process the pending DIO Interrupts. * SRIO Driver users need to ensure that this ISR is plugged with * their OS Interrupt Management API. The function expects the * Interrupt Destination information to be passed along to the * API because the DIO interrupt destination mapping is configurable * during SRIO device initialization. * * @param[in] argument * SRIO Driver Handle * * @retval * Not Applicable */ static void myDioTxCompletionIsr ( UArg argument ) { /* Pass the control to the driver DIO Tx Completion ISR handler */ Srio_dioTxCompletionIsr ((Srio_DrvHandle)argument, hSrioCSL); /* Wake up the pending task */ srioLsuIsrServiced = 1; /* Debug: Increment the ISR count */ srioDbgDioIsrCnt++; return; } /** * @b Description * @n * The function demonstrates usage of interrupts to indicate * the end of DIO transfers * * @param[in] hSrioDrv * Handle to the SRIO driver * * @retval * Success - 0 * @retval * Error - <0 */ static Int32 dioSocketsWithISR (Srio_DrvHandle hSrioDrv, uint8_t dio_ftype, uint8_t dio_ttype) { Srio_SockBindAddrInfo bindInfo; Srio_SockAddrInfo to; uint16_t sockIdx, i, compCode; uint16_t counter, srcDstBufIdx = 0; int32_t eventId, startTime; UInt8 **srcDataBufPtr = NULL, **dstDataBufPtr = NULL; System_printf ("*************************************************************\n"); System_printf ("******* DIO Socket Example with Interrupts (Core %d) ********\n", coreNum); System_printf ("*************************************************************\n"); /* Get the CSL SRIO Handle. */ hSrioCSL = CSL_SRIO_Open (0); if (hSrioCSL == NULL) return -1; /* SRIO DIO Interrupts need to be routed from the CPINTC0 to GEM Event. * - We have configured DIO Interrupts to get routed to Interrupt Destination 0 * (Refer to the CSL_SRIO_RouteLSUInterrupts API configuration in the SRIO Initialization) * - We want this System Interrupt to mapped to Host Interrupt 8 */ /* Disable Interrupt Pacing for INTDST0 */ CSL_SRIO_DisableInterruptPacing (hSrioCSL, 0); /* Route LSU0 ICR0 to INTDST0 */ CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 0, 0); /* Route LSU0 ICR1 to INTDST0 */ CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 1, 0); /* Route LSU0 ICR2 to INTDST0 */ CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 2, 0); /* Map the System Interrupt i.e. the Interrupt Destination 0 interrupt to the DIO ISR Handler. */ CpIntc_dispatchPlug(CSL_INTC0_INTDST0, (CpIntc_FuncPtr)myDioTxCompletionIsr, (UArg)hSrioDrv, TRUE); /* The configuration is for CPINTC0. We map system interrupt 112 to Host Interrupt 8. */ CpIntc_mapSysIntToHostInt(0, CSL_INTC0_INTDST0, 8); /* Enable the Host Interrupt. */ CpIntc_enableHostInt(0, 8); /* Enable the System Interrupt */ CpIntc_enableSysInt(0, CSL_INTC0_INTDST0); /* Get the event id associated with the host interrupt. */ eventId = CpIntc_getEventId(8); /* Plug the CPINTC Dispatcher. */ EventCombiner_dispatchPlug (eventId, CpIntc_dispatch, 8, TRUE); for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { /* Open DIO SRIO Non-Blocking Socket */ srioSocket[sockIdx] = Srio_sockOpen (hSrioDrv, Srio_SocketType_DIO, FALSE); if (srioSocket[sockIdx] == NULL) { System_printf ("Error: Unable to open the DIO socket - %d\n", sockIdx); return -1; } /* DIO Binding Information: Use 16 bit identifiers and we are bound to the first source id. * and we are using 16 bit device identifiers. */ bindInfo.dio.doorbellValid = 0; bindInfo.dio.intrRequest = 1; bindInfo.dio.supInt = 0; bindInfo.dio.xambs = 0; bindInfo.dio.priority = 0; bindInfo.dio.outPortID = 0; bindInfo.dio.idSize = 1; bindInfo.dio.srcIDMap = sockIdx; bindInfo.dio.hopCount = 0; bindInfo.dio.doorbellReg = 0; bindInfo.dio.doorbellBit = 0; /* Bind the SRIO socket: DIO sockets do not need any binding information. */ if (Srio_sockBind_DIO (srioSocket[sockIdx], &bindInfo) < 0) { System_printf ("Error: Binding the SIO socket failed.\n"); return -1; } } /* Allocate memory for the Source and Destination Buffers */ for (i = 0; i < (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS); i++) { srcDataBuffer[i] = (uint8_t*)Osal_srioDataBufferMalloc(SIZE_DIO_PACKET); if (srcDataBuffer[i] == NULL) { System_printf ("Error: Source Buffer (%d) Memory Allocation Failed\n", i); return -1; } dstDataBuffer[i] = (uint8_t*)Osal_srioDataBufferMalloc(SIZE_DIO_PACKET); if (dstDataBuffer[i] == NULL) { System_printf ("Error: Destination Buffer (%d) Memory Allocation Failed\n", i); return -1; } /* Initialize the data buffers */ for (counter = 0; counter < SIZE_DIO_PACKET; counter++) { srcDataBuffer[i][counter] = counter + (i * 5); dstDataBuffer[i][counter] = 0; } /* Debug Message: */ System_printf ("Debug(Core %d): Starting the DIO Data Transfer - Src(%d) 0x%p Dst(%d) 0x%p\n", coreNum, i, srcDataBuffer[i], i, dstDataBuffer[i]); } if ((dio_ftype == Srio_Ftype_WRITE) && (dio_ttype == Srio_Ttype_Write_NWRITE_R)) { /* DIO Write operation */ srcDataBufPtr = &srcDataBuffer[0]; dstDataBufPtr = &dstDataBuffer[0]; } else if ((dio_ftype == Srio_Ftype_REQUEST) && (dio_ttype == Srio_Ttype_Request_NREAD)) { /* DIO Read operation */ srcDataBufPtr = &dstDataBuffer[0]; dstDataBufPtr = &srcDataBuffer[0]; } else { /* Debug Message: */ System_printf ("Debug(Core %d): Unexpected combination of FTYPE and TTYPE. Example couldn't run. Exiting!!!\n", coreNum); return -1; } /********************************************************************************* * Run multiple iterations of the example to ensure multiple data transfers work *********************************************************************************/ for (counter = 0; counter < SRIO_DIO_LSU_ISR_NUM_TRANSFERS; counter++) { for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { /* Populate the DIO Address Information where the data is to be sent. */ to.dio.rapidIOMSB = 0x0; to.dio.rapidIOLSB = (uint32_t)DST; to.dio.dstID = DEVICE_ID4_16BIT; to.dio.ttype = dio_ttype; to.dio.ftype = dio_ftype; /* Send the DIO Information. */ if (Srio_sockSend_DIO (srioSocket[0], srcDataBufPtr[0], SIZE_DIO_PACKET, (Srio_SockAddrInfo*)&to) < 0) { System_printf ("Debug(Core %d): DIO Socket Example Failed\n", coreNum); return -1; } System_printf("RapidIO Address LSB=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG1); System_printf("DSP Address=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG2); System_printf("byte count=%d\n", hSrioCSL->LSU_CMD->RIO_LSU_REG3); System_printf("RIO_LSU_REG4=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG4); System_printf("type=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG5); /* Wait for the interrupt to occur without touching the peripheral. */ /* Other useful work could be done here such as by invoking a scheduler */ startTime = TSCL; while((! srioLsuIsrServiced) && ((TSCL - startTime) < SRIO_DIO_LSU_ISR_TIMEOUT)); if (! srioLsuIsrServiced) { System_printf ("ISR didn't happen within set time - %d cycles. Example failed !!!\n", SRIO_DIO_LSU_ISR_TIMEOUT); return -1; } /* Debug Message: Data Transfer was completed successfully. */ System_printf ("Debug(Core %d): DIO Socket (%d) Send for iteration %d\n", coreNum, sockIdx, counter); /* Read the completion code filled by the ISR */ compCode = 0xFF; if (Srio_getSockOpt(srioSocket[sockIdx], Srio_Opt_DIO_READ_SOCK_COMP_CODE, &compCode, sizeof(uint8_t)) < 0) { System_printf ("Error: Unable to read the completion code in socket\n"); return -1; } /* Was the transfer good. */ if (compCode == 0) { srioDioLsuGoodTransfers++; } else { srioDioLsuBadTransfers++; } /* Clear the LSU pending interrupt (ICCx) */ CSL_SRIO_ClearLSUPendingInterrupt (hSrioCSL, 0xFFFFFFFF, 0xFFFFFFFF); srioLsuIsrServiced = 0; /* Debug Message: Display ISR count */ System_printf ("Debug(Core %d): ISR Count: %d\n", coreNum, srioDbgDioIsrCnt); /* Load next set of payload buffers */ srcDstBufIdx++; if (srcDstBufIdx > (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS)) { System_printf ("Debug(Core %d): DIO Socket Example --- Out of SRC and DST buffers\n", coreNum); return -1; } } } /********************************************************************************* * Run multiple iterations of the example to ensure multiple data transfers work *********************************************************************************/ srcDstBufIdx=0; for (counter = 0; counter < SRIO_DIO_LSU_ISR_NUM_TRANSFERS; counter++) { for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { /* Populate the DIO Address Information where the data is to be sent. */ to.dio.rapidIOMSB = 0x0; to.dio.rapidIOLSB = (uint32_t)DST; to.dio.dstID = DEVICE_ID4_16BIT; to.dio.ttype = Srio_Ttype_Request_NREAD; to.dio.ftype = Srio_Ftype_REQUEST; /* Send the DIO Information. */ if (Srio_sockSend_DIO (srioSocket[0], dstDataBufPtr[0], SIZE_DIO_PACKET, (Srio_SockAddrInfo*)&to) < 0) { System_printf ("Debug(Core %d): DIO Socket Example Failed\n", coreNum); return -1; } System_printf("RapidIO Address LSB=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG1); System_printf("DSP Address=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG2); System_printf("byte count=%d\n", hSrioCSL->LSU_CMD->RIO_LSU_REG3); System_printf("RIO_LSU_REG4=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG4); System_printf("type=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG5); /* Wait for the interrupt to occur without touching the peripheral. */ /* Other useful work could be done here such as by invoking a scheduler */ startTime = TSCL; while((! srioLsuIsrServiced) && ((TSCL - startTime) < SRIO_DIO_LSU_ISR_TIMEOUT)); if (! srioLsuIsrServiced) { System_printf ("ISR didn't happen within set time - %d cycles. Example failed !!!\n", SRIO_DIO_LSU_ISR_TIMEOUT); return -1; } /* Debug Message: Data Transfer was completed successfully. */ System_printf ("Debug(Core %d): DIO Socket (%d) Send for iteration %d\n", coreNum, sockIdx, counter); /* Read the completion code filled by the ISR */ compCode = 0xFF; if (Srio_getSockOpt(srioSocket[sockIdx], Srio_Opt_DIO_READ_SOCK_COMP_CODE, &compCode, sizeof(uint8_t)) < 0) { System_printf ("Error: Unable to read the completion code in socket\n"); return -1; } /* Was the transfer good. */ if (compCode == 0) { srioDioLsuGoodTransfers++; } else { srioDioLsuBadTransfers++; } /* Clear the LSU pending interrupt (ICCx) */ CSL_SRIO_ClearLSUPendingInterrupt (hSrioCSL, 0xFFFFFFFF, 0xFFFFFFFF); srioLsuIsrServiced = 0; /* Debug Message: Display ISR count */ System_printf ("Debug(Core %d): ISR Count: %d\n", coreNum, srioDbgDioIsrCnt); /* Load next set of payload buffers */ srcDstBufIdx++; if (srcDstBufIdx > (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS)) { System_printf ("Debug(Core %d): DIO Socket Example --- Out of SRC and DST buffers\n", coreNum); return -1; } } } // Validate the received buffer. for (i = 0; i < (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS); i++) { for (counter = 0; counter < SIZE_DIO_PACKET; counter++) { if (dstDataBufPtr[i][counter] != srcDataBufPtr[i][counter]) { System_printf ("Error(Core %d): Data Validation error. Buffer Number (%d): Expected 0x%x got 0x%x @ index %d\n", coreNum, i, srcDataBufPtr[i][counter], dstDataBufPtr[i][counter], counter); return -1; } } } // Debug Message: Print error counters // System_printf ("Debug(Core %d): Transfer Completion without Errors - %d\n", coreNum, srioDioLsuGoodTransfers); System_printf ("Debug(Core %d): Transfer Completion with Errors - %d\n", coreNum, srioDioLsuBadTransfers); // Debug Message: Data was validated // System_printf ("Debug(Core %d): DIO Transfer Data Validated for all iterations\n", coreNum); // Cleanup the source & destination buffers. // for (srcDstBufIdx = 0; srcDstBufIdx < (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS); srcDstBufIdx++) { Osal_srioDataBufferFree ((Void*)srcDataBufPtr[srcDstBufIdx], SIZE_DIO_PACKET); Osal_srioDataBufferFree ((Void*)dstDataBufPtr[srcDstBufIdx], SIZE_DIO_PACKET); } // Close the sockets // for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { Srio_sockClose_DIO (srioSocket[sockIdx]); } // Debug Message: Example completed // if ((dio_ftype == Srio_Ftype_WRITE) && (dio_ttype == Srio_Ttype_Write_NWRITE_R)) { System_printf ("Debug(Core %d): DIO Data Transfer (WRITE) with Interrupts Example Passed\n", coreNum); } else if ((dio_ftype == Srio_Ftype_REQUEST) && (dio_ttype == Srio_Ttype_Request_NREAD)) { System_printf ("Debug(Core %d): DIO Data Transfer (READ) with Interrupts Example Passed\n", coreNum); } return 0; } static Int32 dioSocketsWithISR_Write (Srio_DrvHandle hSrioDrv, uint8_t dio_ftype, uint8_t dio_ttype) { Srio_SockBindAddrInfo bindInfo; Srio_SockAddrInfo to; uint16_t sockIdx, i, compCode; uint16_t counter, srcDstBufIdx = 0; int32_t eventId, startTime; UInt8 **srcDataBufPtr = NULL, **dstDataBufPtr = NULL; System_printf ("*************************************************************\n"); System_printf ("******* DIO Socket Example with Interrupts (Core %d) ********\n", coreNum); System_printf ("*************************************************************\n"); /* Get the CSL SRIO Handle. */ hSrioCSL = CSL_SRIO_Open (0); if (hSrioCSL == NULL) return -1; /* SRIO DIO Interrupts need to be routed from the CPINTC0 to GEM Event. * - We have configured DIO Interrupts to get routed to Interrupt Destination 0 * (Refer to the CSL_SRIO_RouteLSUInterrupts API configuration in the SRIO Initialization) * - We want this System Interrupt to mapped to Host Interrupt 8 */ /* Disable Interrupt Pacing for INTDST0 */ CSL_SRIO_DisableInterruptPacing (hSrioCSL, 0); /* Route LSU0 ICR0 to INTDST0 */ CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 0, 0); /* Route LSU0 ICR1 to INTDST0 */ CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 1, 0); /* Route LSU0 ICR2 to INTDST0 */ CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 2, 0); /* Map the System Interrupt i.e. the Interrupt Destination 0 interrupt to the DIO ISR Handler. */ CpIntc_dispatchPlug(CSL_INTC0_INTDST0, (CpIntc_FuncPtr)myDioTxCompletionIsr, (UArg)hSrioDrv, TRUE); /* The configuration is for CPINTC0. We map system interrupt 112 to Host Interrupt 8. */ CpIntc_mapSysIntToHostInt(0, CSL_INTC0_INTDST0, 8); /* Enable the Host Interrupt. */ CpIntc_enableHostInt(0, 8); /* Enable the System Interrupt */ CpIntc_enableSysInt(0, CSL_INTC0_INTDST0); /* Get the event id associated with the host interrupt. */ eventId = CpIntc_getEventId(8); /* Plug the CPINTC Dispatcher. */ EventCombiner_dispatchPlug (eventId, CpIntc_dispatch, 8, TRUE); for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { /* Open DIO SRIO Non-Blocking Socket */ srioSocket[sockIdx] = Srio_sockOpen (hSrioDrv, Srio_SocketType_DIO, FALSE); if (srioSocket[sockIdx] == NULL) { System_printf ("Error: Unable to open the DIO socket - %d\n", sockIdx); return -1; } /* DIO Binding Information: Use 16 bit identifiers and we are bound to the first source id. * and we are using 16 bit device identifiers. */ bindInfo.dio.doorbellValid = 0; bindInfo.dio.intrRequest = 1; bindInfo.dio.supInt = 0; bindInfo.dio.xambs = 0; bindInfo.dio.priority = 0; bindInfo.dio.outPortID = 0; bindInfo.dio.idSize = 1; bindInfo.dio.srcIDMap = sockIdx; bindInfo.dio.hopCount = 0; bindInfo.dio.doorbellReg = 0; bindInfo.dio.doorbellBit = 0; /* Bind the SRIO socket: DIO sockets do not need any binding information. */ if (Srio_sockBind_DIO (srioSocket[sockIdx], &bindInfo) < 0) { System_printf ("Error: Binding the SIO socket failed.\n"); return -1; } } /* Allocate memory for the Source and Destination Buffers */ for (i = 0; i < (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS); i++) { srcDataBuffer[i] = (uint8_t*)Osal_srioDataBufferMalloc(SIZE_DIO_PACKET); if (srcDataBuffer[i] == NULL) { System_printf ("Error: Source Buffer (%d) Memory Allocation Failed\n", i); return -1; } dstDataBuffer[i] = (uint8_t*)Osal_srioDataBufferMalloc(SIZE_DIO_PACKET); if (dstDataBuffer[i] == NULL) { System_printf ("Error: Destination Buffer (%d) Memory Allocation Failed\n", i); return -1; } /* Initialize the data buffers */ for (counter = 0; counter < SIZE_DIO_PACKET; counter++) { srcDataBuffer[i][counter] = counter + (i * 5); dstDataBuffer[i][counter] = 0; } /* Debug Message: */ System_printf ("Debug(Core %d): Starting the DIO Data Transfer - Src(%d) 0x%p Dst(%d) 0x%p\n", coreNum, i, srcDataBuffer[i], i, dstDataBuffer[i]); } if ((dio_ftype == Srio_Ftype_WRITE) && (dio_ttype == Srio_Ttype_Write_NWRITE_R)) { /* DIO Write operation */ srcDataBufPtr = &srcDataBuffer[0]; dstDataBufPtr = &dstDataBuffer[0]; } else if ((dio_ftype == Srio_Ftype_REQUEST) && (dio_ttype == Srio_Ttype_Request_NREAD)) { /* DIO Read operation */ srcDataBufPtr = &dstDataBuffer[0]; dstDataBufPtr = &srcDataBuffer[0]; } else { /* Debug Message: */ System_printf ("Debug(Core %d): Unexpected combination of FTYPE and TTYPE. Example couldn't run. Exiting!!!\n", coreNum); return -1; } /********************************************************************************* * Run multiple iterations of the example to ensure multiple data transfers work *********************************************************************************/ for (counter = 0; counter < SRIO_DIO_LSU_ISR_NUM_TRANSFERS; counter++) { for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { /* Populate the DIO Address Information where the data is to be sent. */ to.dio.rapidIOMSB = 0x0; to.dio.rapidIOLSB = (uint32_t)DST; to.dio.dstID = DEVICE_ID4_16BIT; to.dio.ttype = dio_ttype; to.dio.ftype = dio_ftype; /* Send the DIO Information. */ if (Srio_sockSend_DIO (srioSocket[0], srcDataBufPtr[0], SIZE_DIO_PACKET, (Srio_SockAddrInfo*)&to) < 0) { System_printf ("Debug(Core %d): DIO Socket Example Failed\n", coreNum); return -1; } System_printf("RapidIO Address LSB=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG1); System_printf("DSP Address=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG2); System_printf("byte count=%d\n", hSrioCSL->LSU_CMD->RIO_LSU_REG3); System_printf("RIO_LSU_REG4=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG4); System_printf("type=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG5); /* Wait for the interrupt to occur without touching the peripheral. */ /* Other useful work could be done here such as by invoking a scheduler */ startTime = TSCL; while((! srioLsuIsrServiced) && ((TSCL - startTime) < SRIO_DIO_LSU_ISR_TIMEOUT)); if (! srioLsuIsrServiced) { System_printf ("ISR didn't happen within set time - %d cycles. Example failed !!!\n", SRIO_DIO_LSU_ISR_TIMEOUT); return -1; } /* Debug Message: Data Transfer was completed successfully. */ System_printf ("Debug(Core %d): DIO Socket (%d) Send for iteration %d\n", coreNum, sockIdx, counter); /* Read the completion code filled by the ISR */ compCode = 0xFF; if (Srio_getSockOpt(srioSocket[sockIdx], Srio_Opt_DIO_READ_SOCK_COMP_CODE, &compCode, sizeof(uint8_t)) < 0) { System_printf ("Error: Unable to read the completion code in socket\n"); return -1; } /* Was the transfer good. */ if (compCode == 0) { srioDioLsuGoodTransfers++; } else { srioDioLsuBadTransfers++; } /* Clear the LSU pending interrupt (ICCx) */ CSL_SRIO_ClearLSUPendingInterrupt (hSrioCSL, 0xFFFFFFFF, 0xFFFFFFFF); srioLsuIsrServiced = 0; /* Debug Message: Display ISR count */ System_printf ("Debug(Core %d): ISR Count: %d\n", coreNum, srioDbgDioIsrCnt); /* Load next set of payload buffers */ srcDstBufIdx++; if (srcDstBufIdx > (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS)) { System_printf ("Debug(Core %d): DIO Socket Example --- Out of SRC and DST buffers\n", coreNum); return -1; } } } // Validate the received buffer. for (i = 0; i < (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS); i++) { for (counter = 0; counter < SIZE_DIO_PACKET; counter++) { if (dstDataBufPtr[i][counter] != srcDataBufPtr[i][counter]) { System_printf ("Error(Core %d): Data Validation error. Buffer Number (%d): Expected 0x%x got 0x%x @ index %d\n", coreNum, i, srcDataBufPtr[i][counter], dstDataBufPtr[i][counter], counter); return -1; } } } // Debug Message: Print error counters // System_printf ("Debug(Core %d): Transfer Completion without Errors - %d\n", coreNum, srioDioLsuGoodTransfers); System_printf ("Debug(Core %d): Transfer Completion with Errors - %d\n", coreNum, srioDioLsuBadTransfers); // Debug Message: Data was validated // System_printf ("Debug(Core %d): DIO Transfer Data Validated for all iterations\n", coreNum); // Cleanup the source & destination buffers. // for (srcDstBufIdx = 0; srcDstBufIdx < (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS); srcDstBufIdx++) { Osal_srioDataBufferFree ((Void*)srcDataBufPtr[srcDstBufIdx], SIZE_DIO_PACKET); Osal_srioDataBufferFree ((Void*)dstDataBufPtr[srcDstBufIdx], SIZE_DIO_PACKET); } // Close the sockets // for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { Srio_sockClose_DIO (srioSocket[sockIdx]); } // Debug Message: Example completed // if ((dio_ftype == Srio_Ftype_WRITE) && (dio_ttype == Srio_Ttype_Write_NWRITE_R)) { System_printf ("Debug(Core %d): DIO Data Transfer (WRITE) with Interrupts Example Passed\n", coreNum); } else if ((dio_ftype == Srio_Ftype_REQUEST) && (dio_ttype == Srio_Ttype_Request_NREAD)) { System_printf ("Debug(Core %d): DIO Data Transfer (READ) with Interrupts Example Passed\n", coreNum); } return 0; } static Int32 dioSocketsWithISR_Read (Srio_DrvHandle hSrioDrv, uint8_t dio_ftype, uint8_t dio_ttype) { Srio_SockBindAddrInfo bindInfo; Srio_SockAddrInfo to; uint16_t sockIdx, i, compCode; uint16_t counter, srcDstBufIdx = 0; int32_t eventId, startTime; UInt8 **srcDataBufPtr = NULL, **dstDataBufPtr = NULL; System_printf ("*************************************************************\n"); System_printf ("******* DIO Socket Example with Interrupts (Core %d) ********\n", coreNum); System_printf ("*************************************************************\n"); /* Get the CSL SRIO Handle. */ hSrioCSL = CSL_SRIO_Open (0); if (hSrioCSL == NULL) return -1; /* SRIO DIO Interrupts need to be routed from the CPINTC0 to GEM Event. * - We have configured DIO Interrupts to get routed to Interrupt Destination 0 * (Refer to the CSL_SRIO_RouteLSUInterrupts API configuration in the SRIO Initialization) * - We want this System Interrupt to mapped to Host Interrupt 8 */ /* Disable Interrupt Pacing for INTDST0 */ CSL_SRIO_DisableInterruptPacing (hSrioCSL, 0); /* Route LSU0 ICR0 to INTDST0 */ CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 0, 0); /* Route LSU0 ICR1 to INTDST0 */ CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 1, 0); /* Route LSU0 ICR2 to INTDST0 */ CSL_SRIO_RouteLSUInterrupts (hSrioCSL, 2, 0); /* Map the System Interrupt i.e. the Interrupt Destination 0 interrupt to the DIO ISR Handler. */ CpIntc_dispatchPlug(CSL_INTC0_INTDST0, (CpIntc_FuncPtr)myDioTxCompletionIsr, (UArg)hSrioDrv, TRUE); /* The configuration is for CPINTC0. We map system interrupt 112 to Host Interrupt 8. */ CpIntc_mapSysIntToHostInt(0, CSL_INTC0_INTDST0, 8); /* Enable the Host Interrupt. */ CpIntc_enableHostInt(0, 8); /* Enable the System Interrupt */ CpIntc_enableSysInt(0, CSL_INTC0_INTDST0); /* Get the event id associated with the host interrupt. */ eventId = CpIntc_getEventId(8); /* Plug the CPINTC Dispatcher. */ EventCombiner_dispatchPlug (eventId, CpIntc_dispatch, 8, TRUE); for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { /* Open DIO SRIO Non-Blocking Socket */ srioSocket[sockIdx] = Srio_sockOpen (hSrioDrv, Srio_SocketType_DIO, FALSE); if (srioSocket[sockIdx] == NULL) { System_printf ("Error: Unable to open the DIO socket - %d\n", sockIdx); return -1; } /* DIO Binding Information: Use 16 bit identifiers and we are bound to the first source id. * and we are using 16 bit device identifiers. */ bindInfo.dio.doorbellValid = 0; bindInfo.dio.intrRequest = 1; bindInfo.dio.supInt = 0; bindInfo.dio.xambs = 0; bindInfo.dio.priority = 0; bindInfo.dio.outPortID = 0; bindInfo.dio.idSize = 1; bindInfo.dio.srcIDMap = sockIdx; bindInfo.dio.hopCount = 0; bindInfo.dio.doorbellReg = 0; bindInfo.dio.doorbellBit = 0; /* Bind the SRIO socket: DIO sockets do not need any binding information. */ if (Srio_sockBind_DIO (srioSocket[sockIdx], &bindInfo) < 0) { System_printf ("Error: Binding the SIO socket failed.\n"); return -1; } } /* Allocate memory for the Source and Destination Buffers */ for (i = 0; i < (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS); i++) { srcDataBuffer[i] = (uint8_t*)Osal_srioDataBufferMalloc(SIZE_DIO_PACKET); if (srcDataBuffer[i] == NULL) { System_printf ("Error: Source Buffer (%d) Memory Allocation Failed\n", i); return -1; } dstDataBuffer[i] = (uint8_t*)Osal_srioDataBufferMalloc(SIZE_DIO_PACKET); if (dstDataBuffer[i] == NULL) { System_printf ("Error: Destination Buffer (%d) Memory Allocation Failed\n", i); return -1; } /* Initialize the data buffers */ for (counter = 0; counter < SIZE_DIO_PACKET; counter++) { srcDataBuffer[i][counter] = 0xff; dstDataBuffer[i][counter] = 0xff; } /* Debug Message: */ System_printf ("Debug(Core %d): Starting the DIO Data Transfer - Src(%d) 0x%p Dst(%d) 0x%p\n", coreNum, i, srcDataBuffer[i], i, dstDataBuffer[i]); } if ((dio_ftype == Srio_Ftype_WRITE) && (dio_ttype == Srio_Ttype_Write_NWRITE_R)) { /* DIO Write operation */ srcDataBufPtr = &srcDataBuffer[0]; dstDataBufPtr = &dstDataBuffer[0]; } else if ((dio_ftype == Srio_Ftype_REQUEST) && (dio_ttype == Srio_Ttype_Request_NREAD)) { /* DIO Read operation */ srcDataBufPtr = &dstDataBuffer[0]; dstDataBufPtr = &srcDataBuffer[0]; } else { /* Debug Message: */ System_printf ("Debug(Core %d): Unexpected combination of FTYPE and TTYPE. Example couldn't run. Exiting!!!\n", coreNum); return -1; } /********************************************************************************* * Run multiple iterations of the example to ensure multiple data transfers work *********************************************************************************/ for (counter = 0; counter < SRIO_DIO_LSU_ISR_NUM_TRANSFERS; counter++) { for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { /* Populate the DIO Address Information where the data is to be sent. */ to.dio.rapidIOMSB = 0x0; to.dio.rapidIOLSB = (uint32_t)DST; to.dio.dstID = DEVICE_ID4_16BIT; to.dio.ttype = dio_ttype; to.dio.ftype = dio_ftype; //for (i=0; i<40; i++) /* Send the DIO Information. */ if (Srio_sockSend_DIO (srioSocket[0], srcDataBufPtr[0], SIZE_DIO_PACKET, (Srio_SockAddrInfo*)&to) < 0) { System_printf ("Debug(Core %d): DIO Socket Example Failed\n", coreNum); return -1; } /* Wait for the interrupt to occur without touching the peripheral. */ /* Other useful work could be done here such as by invoking a scheduler */ startTime = TSCL; while((! srioLsuIsrServiced) && ((TSCL - startTime) < SRIO_DIO_LSU_ISR_TIMEOUT)); if (! srioLsuIsrServiced) { System_printf ("ISR didn't happen within set time - %d cycles. Example failed !!!\n", SRIO_DIO_LSU_ISR_TIMEOUT); return -1; } System_printf("RapidIO Address LSB=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG1); System_printf("DSP Address=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG2); System_printf("byte count=%d\n", hSrioCSL->LSU_CMD->RIO_LSU_REG3); System_printf("RIO_LSU_REG4=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG4); System_printf("type=%x\n", hSrioCSL->LSU_CMD->RIO_LSU_REG5); /* Debug Message: Data Transfer was completed successfully. */ System_printf ("Debug(Core %d): DIO Socket (%d) Send for iteration %d\n", coreNum, sockIdx, counter); /* Read the completion code filled by the ISR */ compCode = 0xFF; if (Srio_getSockOpt(srioSocket[0], Srio_Opt_DIO_READ_SOCK_COMP_CODE, &compCode, sizeof(uint8_t)) < 0) { System_printf ("Error: Unable to read the completion code in socket\n"); return -1; } /* Was the transfer good. */ if (compCode == 0) { srioDioLsuGoodTransfers++; } else { srioDioLsuBadTransfers++; } /* Clear the LSU pending interrupt (ICCx) */ CSL_SRIO_ClearLSUPendingInterrupt (hSrioCSL, 0xFFFFFFFF, 0xFFFFFFFF); srioLsuIsrServiced = 0; /* Debug Message: Display ISR count */ System_printf ("Debug(Core %d): ISR Count: %d\n", coreNum, srioDbgDioIsrCnt); /* Load next set of payload buffers */ srcDstBufIdx++; if (srcDstBufIdx > (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS)) { System_printf ("Debug(Core %d): DIO Socket Example --- Out of SRC and DST buffers\n", coreNum); return -1; } } } // Validate the received buffer. for (i = 0; i < (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS); i++) { for (counter = 0; counter < SIZE_DIO_PACKET; counter++) { if (dstDataBufPtr[i][counter] != srcDataBufPtr[i][counter]) { System_printf ("Error(Core %d): Data Validation error. Buffer Number (%d): Expected 0x%x got 0x%x @ index %d\n", coreNum, i, srcDataBufPtr[i][counter], dstDataBufPtr[i][counter], counter); return -1; } } } // Debug Message: Print error counters // System_printf ("Debug(Core %d): Transfer Completion without Errors - %d\n", coreNum, srioDioLsuGoodTransfers); System_printf ("Debug(Core %d): Transfer Completion with Errors - %d\n", coreNum, srioDioLsuBadTransfers); // Debug Message: Data was validated // System_printf ("Debug(Core %d): DIO Transfer Data Validated for all iterations\n", coreNum); // Cleanup the source & destination buffers. // for (srcDstBufIdx = 0; srcDstBufIdx < (SRIO_DIO_LSU_ISR_NUM_SOCKETS * SRIO_DIO_LSU_ISR_NUM_TRANSFERS); srcDstBufIdx++) { Osal_srioDataBufferFree ((Void*)srcDataBufPtr[srcDstBufIdx], SIZE_DIO_PACKET); Osal_srioDataBufferFree ((Void*)dstDataBufPtr[srcDstBufIdx], SIZE_DIO_PACKET); } // Close the sockets // for (sockIdx = 0; sockIdx < SRIO_DIO_LSU_ISR_NUM_SOCKETS; sockIdx++) { Srio_sockClose_DIO (srioSocket[sockIdx]); } // Debug Message: Example completed // if ((dio_ftype == Srio_Ftype_WRITE) && (dio_ttype == Srio_Ttype_Write_NWRITE_R)) { System_printf ("Debug(Core %d): DIO Data Transfer (WRITE) with Interrupts Example Passed\n", coreNum); } else if ((dio_ftype == Srio_Ftype_REQUEST) && (dio_ttype == Srio_Ttype_Request_NREAD)) { System_printf ("Debug(Core %d): DIO Data Transfer (READ) with Interrupts Example Passed\n", coreNum); } return 0; } /** * @b Description * @n * System Initialization Code. This is added here only for illustrative * purposes and needs to be invoked once during initialization at * system startup. * * @retval * Success - 0 * @retval * Error - <0 */ static Int32 system_init (Void) { Int32 result; Qmss_MemRegInfo memRegInfo; /* Initialize the QMSS Configuration block. */ memset (&qmssInitConfig, 0, sizeof (Qmss_InitCfg)); /* Initialize the Host Region. */ memset ((void *)&host_region, 0, sizeof(host_region)); /* Set up the linking RAM. Use the internal Linking RAM. * LLD will configure the internal linking RAM address and maximum internal linking RAM size if * a value of zero is specified. Linking RAM1 is not used */ qmssInitConfig.linkingRAM0Base = 0; qmssInitConfig.linkingRAM0Size = 0; qmssInitConfig.linkingRAM1Base = 0; qmssInitConfig.maxDescNum = NUM_HOST_DESC; #ifdef xdc_target__bigEndian /* PDSP Configuration: Big Endian */ qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1; qmssInitConfig.pdspFirmware[0].firmware = &acc48_be; qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_be); #else /* PDSP Configuration: Little Endian */ qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1; qmssInitConfig.pdspFirmware[0].firmware = &acc48_le; qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_le); #endif /* Initialize Queue Manager Sub System */ result = Qmss_init (&qmssInitConfig, &qmssGblCfgParams); if (result != QMSS_SOK) { System_printf ("Error initializing Queue Manager SubSystem error code : %d\n", result); return -1; } /* Start the QMSS. */ if (Qmss_start() != QMSS_SOK) { System_printf ("Error: Unable to start the QMSS\n"); return -1; } /* Memory Region 0 Configuration */ memRegInfo.descBase = (UInt32 *)l2_global_address((UInt32)host_region); memRegInfo.descSize = SIZE_HOST_DESC; memRegInfo.descNum = NUM_HOST_DESC; memRegInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR; memRegInfo.memRegion = Qmss_MemRegion_MEMORY_REGION_NOT_SPECIFIED; /* Initialize and inset the memory region. */ result = Qmss_insertMemoryRegion (&memRegInfo); if (result < QMSS_SOK) { System_printf ("Error inserting memory region: %d\n", result); return -1; } /* Initialize CPPI CPDMA */ result = Cppi_init (&cppiGblCfgParams); if (result != CPPI_SOK) { System_printf ("Error initializing Queue Manager SubSystem error code : %d\n", result); return -1; } /* CPPI and Queue Manager are initialized. */ System_printf ("Debug(Core %d): Queue Manager and CPPI are initialized.\n", coreNum); System_printf ("Debug(Core %d): Host Region 0x%x\n", coreNum, host_region); return 0; } /** * @b Description * @n * Application Raw Receive Cleanup API. * * @retval * Not Applicable. */ static void myAppRawRxFree(Srio_DrvBuffer hDrvBuffer) { Qmss_QueueHnd returnQueueHnd; /* Get the return queue. */ returnQueueHnd = Qmss_getQueueHandle(Cppi_getReturnQueue(Cppi_DescType_HOST, (Cppi_Desc*)hDrvBuffer)); /* Push the descriptor into the return queue. */ Qmss_queuePushDescSize (returnQueueHnd, (Ptr)hDrvBuffer, sizeof(Cppi_HostDesc)); } /** * @b Description * @n * This is the main DIO Example Task * * @retval * Not Applicable. */ static Void dioExampleTask(UArg arg0, UArg arg1) { Qmss_QueueHnd myRxFreeQueueHnd; Qmss_QueueHnd myRxCompletionQueueHnd; Qmss_QueueHnd tmpQueueHnd; UInt32 numAllocated; UInt8 isAllocated; Cppi_DescCfg descCfg; UInt16 index; Cppi_HostDesc* ptrHostDesc; UInt8* ptrRxData; UInt32 numRxBuffers; Srio_DrvConfig appCfg; Srio_DrvConfig drvCfg; Qmss_Queue queueInfo; /* Initialize the SRIO Driver Configuration. */ memset ((Void *)&appCfg, 0, sizeof(Srio_DrvConfig)); /* Initialize the SRIO Driver Configuration. */ memset ((Void *)&drvCfg, 0, sizeof(Srio_DrvConfig)); /* Initialize the OSAL */ if (Osal_dataBufferInitMemory(SRIO_MAX_MTU) < 0) { System_printf ("Error: Unable to initialize the OSAL. \n"); return; } /******************************************************************************** * The SRIO Driver Instance is going to be created with the following properties: * - Application Managed * - Receive Completion Queue is Application specified; which implies that there * is no interrupt support. Applications will hence need to poll the queue to * check if there is data available or not. * - The Receive Free Descriptor Queues along with the Size thresholds are * managed and created by the application. ********************************************************************************/ /* Create the application receive free queue. */ myRxFreeQueueHnd = Qmss_queueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, QMSS_PARAM_NOT_SPECIFIED, &isAllocated); if (myRxFreeQueueHnd < 0) { System_printf ("Error: Unable to create application receive queues.\n"); return; } /* Create the application receive completion queue. */ myRxCompletionQueueHnd = Qmss_queueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, QMSS_PARAM_NOT_SPECIFIED, &isAllocated); if (myRxCompletionQueueHnd < 0) { System_printf ("Error: Unable to create the application receive completion queue.\n"); return; } /* Debug Message: */ System_printf ("Debug(Core %d): AppConfig RxFreeQueue: 0x%x RxCompletionQueue: 0x%x\n", coreNum, myRxFreeQueueHnd, myRxCompletionQueueHnd); /* We are going to be using 4 receive buffers in this example. */ numRxBuffers = 4; /* Application created queue which stores all the receive buffers. */ descCfg.memRegion = Qmss_MemRegion_MEMORY_REGION0; descCfg.descNum = numRxBuffers; descCfg.destQueueNum = QMSS_PARAM_NOT_SPECIFIED; descCfg.queueType = Qmss_QueueType_GENERAL_PURPOSE_QUEUE; descCfg.initDesc = Cppi_InitDesc_INIT_DESCRIPTOR; descCfg.descType = Cppi_DescType_HOST; descCfg.returnQueue = Qmss_getQueueNumber(myRxFreeQueueHnd); descCfg.epibPresent = Cppi_EPIB_NO_EPIB_PRESENT; descCfg.returnPushPolicy = Qmss_Location_HEAD; descCfg.cfg.host.returnPolicy = Cppi_ReturnPolicy_RETURN_ENTIRE_PACKET; descCfg.cfg.host.psLocation = Cppi_PSLoc_PS_IN_DESC; tmpQueueHnd = Cppi_initDescriptor (&descCfg, &numAllocated); if (tmpQueueHnd < 0) { System_printf ("Error: Unable to create application receive queues.\n"); return; } /* Initialize the application receive buffers. */ for (index = 0; index < descCfg.descNum; index++) { /* Pop off a descriptor */ ptrHostDesc = (Cppi_HostDesc *)Qmss_queuePop(tmpQueueHnd); if (ptrHostDesc == NULL) return; /* Allocate the receive buffer where the data will be received into by the SRIO CPDMA. */ ptrRxData = (UInt8*)Osal_srioDataBufferMalloc(SRIO_MAX_MTU); if (ptrRxData == NULL) return; /* Set the DATA and ORIGNAL DATA in the buffer descriptor. */ Cppi_setData (Cppi_DescType_HOST, (Cppi_Desc*)ptrHostDesc, (UInt8*)ptrRxData, SRIO_MAX_MTU); Cppi_setOriginalBufInfo (Cppi_DescType_HOST, (Cppi_Desc*)ptrHostDesc, (UInt8*)ptrRxData, SRIO_MAX_MTU); /* Add the packet descriptor to the Application Receive Free Queue. */ Qmss_queuePushDescSize (myRxFreeQueueHnd, (UInt32*)ptrHostDesc, SIZE_HOST_DESC); } /* Close the temporary queue. */ Qmss_queueClose (tmpQueueHnd); /* Setup the SRIO Driver Configuration: This is application managed configuration */ appCfg.bAppManagedConfig = TRUE; /* Get the queue information about the receive completion queue. */ queueInfo = Qmss_getQueueNumber(myRxCompletionQueueHnd); /* The application managed configuration is capable of reception. */ appCfg.u.appManagedCfg.bIsRxFlowCfgValid = 1; /* Configure the Receive Flow */ appCfg.u.appManagedCfg.rxFlowCfg.flowIdNum = -1; appCfg.u.appManagedCfg.rxFlowCfg.rx_dest_qnum = queueInfo.qNum; appCfg.u.appManagedCfg.rxFlowCfg.rx_dest_qmgr = queueInfo.qMgr; appCfg.u.appManagedCfg.rxFlowCfg.rx_sop_offset = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_ps_location = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_desc_type = 0x1; /* Host Descriptor. */ appCfg.u.appManagedCfg.rxFlowCfg.rx_error_handling = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_psinfo_present = 0x1; /* PS Information */ appCfg.u.appManagedCfg.rxFlowCfg.rx_einfo_present = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_dest_tag_lo = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_dest_tag_hi = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_src_tag_lo = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_src_tag_hi = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_dest_tag_lo_sel = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_dest_tag_hi_sel = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_src_tag_lo_sel = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_src_tag_hi_sel = 0x0; /* Disable Receive size thresholds. */ appCfg.u.appManagedCfg.rxFlowCfg.rx_size_thresh0_en = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_size_thresh1_en = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_size_thresh2_en = 0x0; /* Use the Application Receive Free Queue for picking all descriptors. */ queueInfo = Qmss_getQueueNumber(myRxFreeQueueHnd); appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq1_qnum = queueInfo.qNum; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq1_qmgr = queueInfo.qMgr; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq2_qnum = 0; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq2_qmgr = 0; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq3_qnum = 0; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq3_qmgr = 0; /* Use the Receive Queue for picking the SOP packet also. */ appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq0_sz0_qnum = queueInfo.qNum; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq0_sz0_qmgr = queueInfo.qMgr; /* There are no size thresholds configured. */ appCfg.u.appManagedCfg.rxFlowCfg.rx_size_thresh0 = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_size_thresh1 = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_size_thresh2 = 0x0; /* The other threshold queues do not need to be configured */ appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq0_sz1_qnum = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq0_sz1_qmgr = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq0_sz2_qnum = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq0_sz2_qmgr = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq0_sz3_qnum = 0x0; appCfg.u.appManagedCfg.rxFlowCfg.rx_fdq0_sz3_qmgr = 0x0; /* Polling Mode: So dont program the accumulator. */ appCfg.u.appManagedCfg.bIsAccumlatorCfgValid = 0; /* Populate the rest of the configuration. */ appCfg.u.appManagedCfg.rawRxFreeDrvBuffer = myAppRawRxFree; /* Start the application Managed SRIO Driver. */ hAppManagedSrioDrv = Srio_start(&appCfg); if (hAppManagedSrioDrv == NULL) { System_printf ("Error(Core %d): Application Managed SRIO Driver failed to start\n", coreNum); return; } /******************************************************************************** * The SRIO Driver Instance is going to be created with the following properties: * - Driver Managed * - Interrupt Support (Pass the Rx Completion Queue as NULL) ********************************************************************************/ /* Setup the SRIO Driver Managed Configuration. */ drvCfg.bAppManagedConfig = FALSE; /* Driver Managed: Receive Configuration */ drvCfg.u.drvManagedCfg.bIsRxCfgValid = 1; drvCfg.u.drvManagedCfg.rxCfg.rxMemRegion = Qmss_MemRegion_MEMORY_REGION0; drvCfg.u.drvManagedCfg.rxCfg.numRxBuffers = 4; drvCfg.u.drvManagedCfg.rxCfg.rxMTU = SRIO_MAX_MTU; /* Accumulator Configuration. */ { int32_t coreToQueueSelector[4]; /* This is the table which maps the core to a specific receive queue. */ coreToQueueSelector[0] = 704; coreToQueueSelector[1] = 705; coreToQueueSelector[2] = 706; coreToQueueSelector[3] = 707; /* Since we are programming the accumulator we want this queue to be a HIGH PRIORITY Queue */ drvCfg.u.drvManagedCfg.rxCfg.rxCompletionQueue = Qmss_queueOpen (Qmss_QueueType_HIGH_PRIORITY_QUEUE, coreToQueueSelector[coreNum], &isAllocated); if (drvCfg.u.drvManagedCfg.rxCfg.rxCompletionQueue < 0) { System_printf ("Error: Unable to open the SRIO Receive Completion Queue\n"); return; } /* Accumulator Configuration is VALID. */ drvCfg.u.drvManagedCfg.rxCfg.bIsAccumlatorCfgValid = 1; /* Accumulator Configuration. */ drvCfg.u.drvManagedCfg.rxCfg.accCfg.channel = coreNum; drvCfg.u.drvManagedCfg.rxCfg.accCfg.command = Qmss_AccCmd_ENABLE_CHANNEL; drvCfg.u.drvManagedCfg.rxCfg.accCfg.queueEnMask = 0; drvCfg.u.drvManagedCfg.rxCfg.accCfg.queMgrIndex = coreToQueueSelector[coreNum]; drvCfg.u.drvManagedCfg.rxCfg.accCfg.maxPageEntries = 2; drvCfg.u.drvManagedCfg.rxCfg.accCfg.timerLoadCount = 0; drvCfg.u.drvManagedCfg.rxCfg.accCfg.interruptPacingMode = Qmss_AccPacingMode_LAST_INTERRUPT; drvCfg.u.drvManagedCfg.rxCfg.accCfg.listEntrySize = Qmss_AccEntrySize_REG_D; drvCfg.u.drvManagedCfg.rxCfg.accCfg.listCountMode = Qmss_AccCountMode_ENTRY_COUNT; drvCfg.u.drvManagedCfg.rxCfg.accCfg.multiQueueMode = Qmss_AccQueueMode_SINGLE_QUEUE; /* Initialize the accumulator list memory */ memset ((Void *)&gHiPriAccumList[0], 0, sizeof(gHiPriAccumList)); drvCfg.u.drvManagedCfg.rxCfg.accCfg.listAddress = l2_global_address((UInt32)&gHiPriAccumList[0]); } /* Driver Managed: Transmit Configuration */ drvCfg.u.drvManagedCfg.bIsTxCfgValid = 1; drvCfg.u.drvManagedCfg.txCfg.txMemRegion = Qmss_MemRegion_MEMORY_REGION0; drvCfg.u.drvManagedCfg.txCfg.numTxBuffers = 4; drvCfg.u.drvManagedCfg.txCfg.txMTU = SRIO_MAX_MTU; /* Start the Driver Managed SRIO Driver. */ hDrvManagedSrioDrv = Srio_start(&drvCfg); if (hDrvManagedSrioDrv == NULL) { System_printf ("Error(Core %d): SRIO Driver failed to start\n", coreNum); return; } /* Hook up the SRIO interrupts with the core. */ EventCombiner_dispatchPlug (48, (EventCombiner_FuncPtr)Srio_rxCompletionIsr, (UArg)hDrvManagedSrioDrv, TRUE); EventCombiner_enableEvent(48); /* Run the loopback data transfers on the system initialization core. */ if (coreNum == CORE_SYS_INIT) { #ifndef SIMULATOR_SUPPORT /* DIO is NOT supported on the simulator */ /* DIO Write Operation */ if (dioSocketsWithISR (hDrvManagedSrioDrv, Srio_Ftype_WRITE, Srio_Ttype_Write_NWRITE_R) < 0) { System_printf ("Error: Loopback DIO ISR example for Write operation failed\n"); Task_exit(); } /* DIO Write Operation */ // if (dioSocketsWithISR_Write (hDrvManagedSrioDrv, Srio_Ftype_WRITE, Srio_Ttype_Write_NWRITE_R) < 0) // { // System_printf ("Error: Loopback DIO ISR example for Write operation failed\n"); // Task_exit(); // } /* Reset global counters before next run */ // srioDioLsuGoodTransfers = 0; // srioDioLsuBadTransfers = 0; /* DIO Read Operation */ // if (dioSocketsWithISR_Read (hDrvManagedSrioDrv, Srio_Ftype_REQUEST, Srio_Ttype_Request_NREAD) < 0) // { // System_printf ("Error: Loopback DIO ISR example for Read operation failed\n"); // Task_exit(); // } #endif } /* Print out the Malloc & Free Counter */ System_printf ("Debug(Core %d): Allocation Counter : %d\n", coreNum, malloc_counter); System_printf ("Debug(Core %d): Free Counter : %d\n", coreNum, free_counter); /* Check if there is a memory leak? Since we dont implement a 'deinit' API we need to * be careful in these calculations * - For the Application Managed Driver Instance * There will be 'numRxBuffers' + 1 (Driver Instance) * - For the Driver Managed Driver Instance * There will be 'numRxBuffers' + 'numTxBuffers' + 1 (Driver Instance) * Take these into account while checking for memory leaks. */ if ((numRxBuffers + 1) + free_counter + (drvCfg.u.drvManagedCfg.rxCfg.numRxBuffers + drvCfg.u.drvManagedCfg.txCfg.numTxBuffers + 1) != malloc_counter) { System_printf ("Error: Memory Leak Detected\n"); Task_exit(); } /* Control comes here implies that example passed. */ System_printf ("Debug(Core %d): DIO with Interrupts example completed successfully.\n", coreNum); Task_exit(); } /** * @b Description * @n * Entry point for the example * * @retval * Not Applicable. */ Void main(Void) { Task_Params taskParams; /* Get the core number. */ coreNum = CSL_chipReadReg (CSL_CHIP_DNUM); #ifdef SIMULATOR_SUPPORT #warn SRIO DIO LSU ISR example is not supported on SIMULATOR !!! System_printf ("SRIO DIO LSU ISR example is not supported on SIMULATOR. Exiting!\n"); return; #else System_printf ("Executing the SRIO DIO example on the DEVICE\n"); #endif #ifdef TEST_MULTICORE /* Initialize the heap in shared memory. Using IPC module to do that */ Ipc_start(); #endif /* Initialize the system only if the core was configured to do so. */ if (coreNum == CORE_SYS_INIT) { System_printf ("Debug(Core %d): System Initialization for CPPI & QMSS\n", coreNum); /* System Initialization */ if (system_init() < 0) return; /* Power on SRIO peripheral before using it */ if (enable_srio () < 0) { System_printf ("Error: SRIO PSC Initialization Failed\n"); return; } /* Device Specific SRIO Initializations: This should always be called before * initializing the SRIO Driver. */ if (SrioDevice_init() < 0) return; /* Initialize the SRIO Driver */ if (Srio_init () < 0) { System_printf ("Error: SRIO Driver Initialization Failed\n"); return; } /* SRIO Driver is operational at this time. */ System_printf ("Debug(Core %d): SRIO Driver has been initialized\n", coreNum); /* Write to the SHARED memory location at this point in time. The other cores cannot execute * till the SRIO Driver is up and running. */ isSRIOInitialized = 1; /* The SRIO IP block has been initialized. We need to writeback the cache here because it will * ensure that the rest of the cores which are waiting for SRIO to be initialized would now be * woken up. */ CACHE_wbL1d ((void *) &isSRIOInitialized, 128, CACHE_WAIT); } else { /* All other cores need to wait for the SRIO to be initialized before they proceed. */ System_printf ("Debug(Core %d): Waiting for SRIO to be initialized.\n", coreNum); /* All other cores loop around forever till the SRIO is up and running. * We need to invalidate the cache so that we always read this from the memory. */ while (isSRIOInitialized == 0) CACHE_invL1d ((void *) &isSRIOInitialized, 128, CACHE_WAIT); /* Start the QMSS. */ if (Qmss_start() != QMSS_SOK) { System_printf ("Error: Unable to start the QMSS\n"); return; } System_printf ("Debug(Core %d): SRIO can now be used.\n", coreNum); } /* Create the DIO Example Task.*/ Task_Params_init(&taskParams); Task_create(dioExampleTask, &taskParams, NULL); /* Start the BIOS */ BIOS_start(); }