• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Digital Signal Processors (DSP) » C6000 Multicore DSP » Keystone Multicore Forum (C66, 66A, AM5) » EDMA3 Peripheral Example?
Share
C6000 Multicore DSP
  • Forums
  • Announcements
Options
  • Subscribe via RSS
Resources
  • KeyStone Multicore DSP + ARM Product Folder
  • Keystone II MCSDK Download
  • Keystone II MCSDK User's Guide

  • KeyStone Multicore DSP Product Folder
  • Keystone I BIOS-MCSDK Download
  • Keystone I BIOS-MCSDK User's Guide

  • Keystone I & II Training

  • C6000 Multicore DSP Product Folder
  • C6000 Multicore Devices

  • DESKTOP-LINUX-SDK 01_00_00_07 Download
  • MCSDK-VIDEO 02_01_00_08 Download

  • C6472 and C6474 Online Training
  • Check out
    Multicore Mix blog
    • $core_v2_blog.Current.Name

      Wireless base stations – why monitor the backup battery?

      Posted 3 days ago
      by Raj Radjassamy
      2G, 3G and 4G LTE base stations use lead-acid batteries as the...
    • $core_v2_blog.Current.Name

      Innovation through smart integration – achieving lower power, high performing small cells

      Posted 4 days ago
      by Debbie Greenstreet
      Wireless small cell market activity is accelerating lately and...
    • $core_v2_blog.Current.Name

      Four for Friday: What’s up at the Small Cells World Summit?

      Posted 17 days ago
      by Debbie Greenstreet
      If you are a follower of the wireless technology, you have probably...

    Forums

    EDMA3 Peripheral Example?

    This question is answered
    Erick Higa
    Posted by Erick Higa
    on Mar 08 2012 17:01 PM
    Intellectual820 points

    Are there any examples using the CSL to setup and use the EDMA3 to setup a peripheral (like SPI, TWI, or UART) on a keystone multicore device?  I currently have tried setting it up for the 6670, but am not quite sure what is wrong. 

    CSL_Edma3Handle hModule;
    CSL_Edma3ParamHandle paramHandle0;
    CSL_Edma3ParamHandle paramHandle1;
    CSL_Edma3ChannelAttr chParam;
    CSL_Edma3ChannelObj ChObj0,ChObj1;
    CSL_Edma3ChannelHandle hChannel0,hChannel1;
    CSL_Edma3HwDmaChannelSetup chSetup;
    CSL_Edma3ParamSetup paramSetup;
    CSL_Edma3Obj moduleObj;
    CSL_Edma3CmdIntr regionIntr;
    CSL_Edma3ChannelErr chErrClear;
    CSL_Status EdmaStat;

    #define TEST_ACNT 4
    #define TEST_BCNT 16
    #define TEST_CCNT 1

    bool ti_spi_edma_transfer(void *src, void *dest, uint32 transLen) {
    int i;

    // Module Initialization
    CSL_edma3Init(NULL);

    // Module Open
    hModule = CSL_edma3Open(&moduleObj,2,NULL,&EdmaStat);

    // Channel Open
    chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;
    chSetup.que = CSL_EDMA3_QUE_0;
    chParam.chaNum = CSL_TPCC2_SPIXEVT;
    hChannel0 = CSL_edma3ChannelOpen(&ChObj0,
    2,
    &chParam,
    &EdmaStat);

    // Channel Setup
    chSetup.paramNum = CSL_TPCC2_SPIXEVT;
    CSL_edma3HwChannelSetupQue(hChannel0,chSetup.que);
    CSL_edma3HwChannelSetupParam(hChannel0,chSetup.paramNum);

    chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;
    chSetup.que = CSL_EDMA3_QUE_0;
    chParam.chaNum = CSL_TPCC2_SPIREVT;
    hChannel1 = CSL_edma3ChannelOpen(&ChObj1,
    2,
    &chParam,
    &EdmaStat);

    // Channel Setup
    chSetup.paramNum = CSL_TPCC2_SPIREVT;
    CSL_edma3HwChannelSetupQue(hChannel1,chSetup.que);
    CSL_edma3HwChannelSetupParam(hChannel1,chSetup.paramNum);

    // Parameter Handle Open
    // Open all the handles and keep them ready
    paramHandle0 = CSL_edma3GetParamHandle(hChannel0,CSL_TPCC2_SPIXEVT,NULL);
    paramHandle1 = CSL_edma3GetParamHandle(hChannel1,CSL_TPCC2_SPIREVT,NULL);

    paramSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(TEST_ACNT,TEST_BCNT);

    paramSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(TEST_ACNT,0);

    paramSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
    paramSetup.cCnt = TEST_CCNT;
    paramSetup.option = CSL_EDMA3_OPT_MAKE(FALSE,TRUE,FALSE,TRUE,
    CSL_TPCC2_SPIXEVT,
    CSL_EDMA3_TCC_NORMAL,
    CSL_EDMA3_FIFOWIDTH_NONE,
    FALSE, CSL_EDMA3_SYNC_A,
    CSL_EDMA3_ADDRMODE_INCR,
    CSL_EDMA3_ADDRMODE_INCR);
    paramSetup.srcAddr = (Uint32)src;
    paramSetup.dstAddr = (Uint32)&(SPI_REGS->SPIDAT1);
    paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);

    CSL_edma3ParamSetup(paramHandle0,&paramSetup);

    paramSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(TEST_ACNT,TEST_BCNT);

    paramSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,TEST_ACNT );
    paramSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);
    paramSetup.cCnt = TEST_CCNT;
    paramSetup.option = CSL_EDMA3_OPT_MAKE(FALSE,TRUE,FALSE,TRUE,
    CSL_TPCC2_SPIREVT,
    CSL_EDMA3_TCC_NORMAL,
    CSL_EDMA3_FIFOWIDTH_NONE,
    FALSE, CSL_EDMA3_SYNC_A,
    CSL_EDMA3_ADDRMODE_INCR,
    CSL_EDMA3_ADDRMODE_INCR);
    paramSetup.srcAddr = (Uint32)&(SPI_REGS->SPIBUF);
    paramSetup.dstAddr = (Uint32)dest;
    paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL,0);

    CSL_edma3ParamSetup(paramHandle1,&paramSetup);

    /* clear the EDMA error registers */
    chErrClear.missed = TRUE;
    chErrClear.secEvt = TRUE;
    CSL_edma3HwChannelControl (hChannel0, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);
    CSL_edma3HwChannelControl (hChannel1, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);
    CSL_edma3HwChannelControl (hChannel0, CSL_EDMA3_CMD_CHANNEL_CLEARERR,
    &chErrClear);
    CSL_edma3HwChannelControl (hChannel1, CSL_EDMA3_CMD_CHANNEL_CLEARERR,
    &chErrClear);
    CSL_edma3HwChannelControl (hChannel0, CSL_EDMA3_CMD_CHANNEL_CLEAR, NULL);
    CSL_edma3HwChannelControl (hChannel1, CSL_EDMA3_CMD_CHANNEL_CLEAR, NULL);


    // Trigger channel
    CSL_edma3HwChannelControl(hChannel0,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);
    // Trigger channel
    CSL_edma3HwChannelControl(hChannel1,CSL_EDMA3_CMD_CHANNEL_ENABLE,NULL);



    /* Start I2C */
    SPI_REGS->SPIDAT1 |= (1 << 28); // Hold CS Line
    SPI_REGS->SPIGCR1 |= (1 << 24); // SPI enable bit (should only be set to 1 when ready to enable)

    // Wait for interrupt
    regionIntr.region = CSL_EDMA3_REGION_GLOBAL;
    regionIntr.intr = 0;
    regionIntr.intrh = 0;

    do{
    CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INTRPEND,&regionIntr);
    for(i=0; i < 1000; i++) asm("nop");
    }while (!(regionIntr.intr & 0xC000));// channel 30 & 31


    /* Stop the transmission */
    SPI_REGS->SPIGCR1 &= ~(1 << 24); // SPI enable bit (should only be set to 1 when ready to enable)
    SPI_REGS->SPIDAT1 &= ~(1 << 28); // Hold CS Line

    /* close instance of EDMA */
    CSL_edma3ChannelClose(hChannel0);
    CSL_edma3ChannelClose(hChannel1);
    CSL_edma3Close(hModule);
    }


    KeyStone C6670 I2C edma3 C6670 CSL
    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • xinwei shi
      Posted by xinwei shi
      on Jul 19 2012 12:46 PM
      Prodigy10 points

      Hello,  Aditya ,

      Great to know you start looking at this issue. For your knowledge, we have SPI works in loopback mode as well as communicating with a SPI slave with CPU interrupt.

      SPI+EDMA doesn't work. Thanks.

      Xinwei

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Erick Higa
      Posted by Erick Higa
      on Jul 19 2012 22:31 PM
      Intellectual820 points

      Aditya,

      I have not done an internal loop back, however we have a custom board and we do have SPI working back and forth w/ a different processor with a protocol that is interrupt driven.  However in our final project, we would like to use the EDMA to drive the SPI to take the load off of the Cores on long transfers.

      Erick

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Aditya
      Posted by Aditya
      on Jul 20 2012 00:03 AM
      Expert3355 points

      Xinwei, Erick,

      Thanks. I am trying to get a working project ready for you. At the moment am facing some issues with EDMA missed events on transmit side. I will post a working project once I have it ready. Please be assured that we want to get you a working project as soon as possible.

      Regards,

      Aditya

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • xinwei shi
      Posted by xinwei shi
      on Jul 31 2012 18:03 PM
      Prodigy10 points

      Hello, Aditya

      How is it going for this project? We really need a working version of SPI+DMA right now.  Please update us the progress and the version you have right now.

      Xinwei

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Steven Ji
      Posted by Steven Ji
      on Aug 01 2012 16:18 PM
      Verified Answer
      Verified by Erick Higa
      Expert8835 points

      I attached one SPI+EDMA example test case below, which is based on C6670 CSL.

      The SPI is configured in internal loopback mode and Channel 2 and Channel 3 of EDMA3_CC1 are being used for SPIXEVT and SPIREVT (Table 7-36 in C6670 data manual).

      The source buffer is located in CorePac0 L2 SRAM and being sent to SPI by EDMA. After loopback, the data is received by SPI and being sent to destination buffer located in CorePac1 L2 SRAM by EDMA as well.

      Please take a look and let us know if you need any more info about this. Thanks.

      4670.edma_spi.zip

      Sincerely,

      Steven

      ------------------------------------------------------------------------------------------------------------

      Please click the Verify Answer button on this post if it answers your question.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • xinwei shi
      Posted by xinwei shi
      on Aug 02 2012 11:31 AM
      Prodigy10 points

      Thank you very much, Steven. I really appreciate it. I have your example build and run well on the C6678 evm board. I have one more question: the src and dst buffer in your example is located in the L2SRAM, can I adapt this example to have my receiving dst buffer in the DDR? I want to have a bigger buffer.

      Looking forward your reply!!

      Xinwei

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Steven Ji
      Posted by Steven Ji
      on Aug 02 2012 11:41 AM
      Expert8835 points

      Xinwei,

      Sure. You can define the src/dst anywhere you prefer.

      For example, currently the dst buffer is in ".gem1_data"

      #pragma DATA_SECTION(dstBuf, ".gem1_data")
      #pragma DATA_ALIGN(dstBuf, 8)
      Uint16 dstBuf[BUF_SIZE];

      You can change to DDR SRAM as

      #pragma DATA_SECTION(dstBuf, ".ddrData")
      #pragma DATA_ALIGN(dstBuf, 8)
      Uint16 dstBuf[BUF_SIZE];

      And in the "example.cmd" file, you will see ".ddrData" is pointed to the DDR3_DATA_MEM. In this way, dstBuf is located in DDR SRAM.

      Alternately, you can use pointers of src/dst buffers, instead of pre-allocating them.

      Then you can give the actually memory location to those buffer pointers in the source code.

      But please pay attention to the memory allocation, that the buffers should be overlapped with others.

      Hope it helps.

      Sincerely,

      Steven

      ------------------------------------------------------------------------------------------------------------

      Please click the Verify Answer button on this post if it answers your question.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • xinwei shi
      Posted by xinwei shi
      on Aug 02 2012 18:33 PM
      Prodigy10 points

      Thank you, Steve. Yes, it definitely helps. I have make the DDR+SPI happened in the loopback mode. I have another two questions:

      1) I change the main in the example to a function spidmatest, and I call it in my main before everything start. It works for the first time when I called. The second time, just following the first call, it hangs at Setup_SPI() because the last while loop in this function. Could you please explain why? How to rescue it when I want the DMA happen more than once. (I have it working only once in the SPI working (non-loopback) mode also).

      2) I used the Oscilloscope to measure the time for transfering 350bytes data via SPI working at 50MHZ using the DMA, it takes around 97us. Is that reasonable? I expect it to be shorter.

      Thank you very much!

      Xinwei

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Steven Ji
      Posted by Steven Ji
      on Aug 06 2012 17:42 PM
      Verified Answer
      Verified by Erick Higa
      Expert8835 points

      Xinwei,

      1. The following example attached demonstrates how to trigger the SPI-EDMA transfer for multiple times. Basically, we need to setup reload paramSet for EDMA channels for the continuous peripheral support (refer to section 3.4.3 in EDMA user guide).

      And we can disable/enable the DMAREQEN bit in the SPIINT0 register to re-trigger the TX/RX DMA request.

      2. The throughput calculation is embedded in the attached example as well. If SPI is running at 66MHz the throughput is about 57Mbps. Please take a look at the following document for reference:Throughput Performance Guide for C66x KeyStone Devices (Rev. A)

      0410.edma_spi.zip

      Sincerely,

      Steven

      ------------------------------------------------------------------------------------------------------------

      Please click the Verify Answer button on this post if it answers your question.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • xinwei shi
      Posted by xinwei shi
      on Aug 07 2012 12:54 PM
      Prodigy10 points

      Thank you, Steve. I will look at the new code shortly. Before I got your new example, I had looked the EDMA registers and figured out one way for continuous firing SPI+DMA:. This is what I did:

      1) disable the complete interrupt bit by seting the fourth parameter False in the paramSetup.option call;

      2)write to register ' EDMA1_CH2SECR            *( volatile Uint32* ) (0x02720000 + 0x1040) '  0x4 to clear the ECR bit.

      Yes,  I stop the transfer by seting SPINT0 to 0.

      It works well so far. Could you please let me know if this way is proper? Anything I should be cautions of?

      Thanks.

      Xinwei

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Steven Ji
      Posted by Steven Ji
      on Aug 07 2012 13:53 PM
      Expert8835 points

      If you do not need EDMA generate interrupt at the completion of transfer, you can disable that and clear the secondary event bit as you did.

      Or you can still let EDMA generate interrupt and clear the interrupt pending in ICR (Interrupt Clear Register, offset 0x1070), as shown in the second example.

      I think either way should be fine, as long as it works for your scenario.

      Sincerely,

      Steven

      ------------------------------------------------------------------------------------------------------------

      Please click the Verify Answer button on this post if it answers your question.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • xinwei shi
      Posted by xinwei shi
      on Aug 07 2012 16:54 PM
      Prodigy10 points

      Thank you, Steve. Yes, your code works well.

      What I am currently doing is to receive data from SPI and put them in a large DDR buffer. But it seems 20% slower than using a buffer in L2 SRAM.

      So I am thinking to use L2SRAM buffer and use an DMA completion interrupt so that the ISR can do another DMA from L2SRAM to DDR. Do you think this will be faster? I really appreciate  if you can share the example code of setting up the DMA complete interrupt. Thanks,

      Xinwei

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Erick Higa
      Posted by Erick Higa
      on Aug 07 2012 23:10 PM
      Intellectual820 points

      Hey Steve,

      Thanks for the example, I haven't had a chance to test it out yet, but it looks like it's what I need to get it going

      Erick

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Harikrishna Vuppaladhadiam
      Posted by Harikrishna Vuppaladhadiam
      on Sep 11 2012 11:22 AM
      Expert1575 points

      Hi,

        I tried the same code on c6657. I appreciate if anyone can advise on this problem. 

      Regards,

      Hari

      0830.main.c

      I got first problem where CSL_TPCC_1 is not defined.  I see it defines CSL_TPCC_2. I tried replacing with values 1 or 2. 

      Compilation is fine, But I get struck @ 

      while(!(((CSL_SpiRegsOvly) CSL_SPI_REGS)->SPIFLG & 0x00000100));
      profileRxStart = CSL_tscRead();

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Erick Higa
      Posted by Erick Higa
      on Sep 14 2012 15:59 PM
      Intellectual820 points

      Harikrishna.

      Using TPCC_2 instead of TPCC_1 requires using different edma channels as the SPI is setup for specific channels, so when CSL_EDMA3_CHA_2 is used, that is specific for TPCC_1, so you need to use CSL_TPCC2_SPIXEVT instead (lines 74, 77, 97, and 104). Same thing goes for CSL_EDMA3_CHA_3, you should replace those references with CSL_TPCC2_SPIREVT.

      Lines 167/168 are also specific to edma channels 2 and 3, you'll have to use the defines for those specific channels. and lines 149 and 147 check to see if the the channel 2 and channel 3 bits are also done.

      Hope that helps,

      Erick

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    123
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use