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.

Problem of using EDMA3 to transfer data between DSP6455 and PC host

Hi,

I put a DSP PCB in the PC's PCI slot, and wants to exchange data between DSP and PC through the PCI bus.

But  I met a problem of using EDMA3. I designed to use DSP memory range 0x40000000 to 0x407FFFFF(the first window of 256M space), and set the register PCIADDSUB0 with a value of 0x4E000000 becase the PCI 's BAR3 in PC memory spcae start at 0x4E000000. After these configuration, I found that I could write data manually in DSP's memory space and PC could reads the change of data in the corresponding PCI memory. But I was failed to use EDMA3 to transfer data from DSP memory to PCI memory. I  refered to DSP645X PCI user's guide, set the source address with the value of I want, and the destination address of 0x40000000. The data couldn't transfer to the address.

Another problem is that when I change data at address 0x40000000 manually, other positions' value followed it at a 4 bytes intervals changed to the same value.  

I don't know why. Does anyone know the reason? Please help me.

Thank you!

Cesc Chou

  • Hi Cesc

    For your EDMA3 issue, can you clarify what is the source address that you are using?

    Also, please note that on c6455, TC0 cannot access PCI , so using EDMA3 , you should not submit a PCI transfer request on Q0-TC0. This connectivity/access for various masters including all TCs is mentioned in the datasheet

    http://focus.ti.com/lit/ds/symlink/tms320c6455.pdf (Pg 80, Table 4-1). You should be able to use all other Q/TC except TC0 for PCI transfers.

    Hope this helps.

    Regards

    Mukul

  • If you are following the EDMA example setup code in the PCI user guide, you may have set SAM=DAM=1.  That is not a correct configuration.  Both SAM and DAM should be set to 0.  We'll get this corrected.

  • Hi Mukul

    There are my configurations of EDMA:

    /* Edma parameter entry Setup */
        myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
                                                 CSL_EDMA3_TCCH_DIS, \
                                                 CSL_EDMA3_ITCINT_DIS, \
                                                 CSL_EDMA3_TCINT_EN,\
                                                 1,CSL_EDMA3_TCC_NORMAL,\
                                                 CSL_EDMA3_FIFOWIDTH_NONE, \
                                                 CSL_EDMA3_STATIC_DIS, \
                                                 CSL_EDMA3_SYNC_A, \
                                                 CSL_EDMA3_ADDRMODE_INCR, \
                                                 CSL_EDMA3_ADDRMODE_INCR); 
        myParamSetup.srcAddr = (Uint32)srcBuff;        //in my program srcBuff is allocated in DDR2 with the address of 0xE0000000      
        myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(512,1);      
        myParamSetup.dstAddr = (Uint32)0x40000000; //first master window with the range from 40000000 to 407fffff       
        myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0,0);    
        myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE (CSL_EDMA3_LINK_NULL,
                                                               1);
        myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,0);    
        myParamSetup.cCnt = 1;         
        status = CSL_edma3ParamSetup(hParamBasic,&myParamSetup);  

    and I change the TC0 to TC1 through this exchange:
    dmahwSetup.que      = CSL_EDMA3_QUE_0;
    to
    dmahwSetup.que      = CSL_EDMA3_QUE_1;

    The data of source is produced by the following sentences:
    for(i=0;i<512;i++)
    {
        SourceAddr[i] = i;
    }

    But there is still some problem in destination memory:
      memory              data
    0x40000000       0x00000005E
    0x40000004       0xFFFFFFFF
    0x40000008       0x00000005E
    0x4000000C       0xFFFFFFFF
    0x40000014       0x00000005E
    0x40000018       0xFFFFFFFF
                      ……
    As you see, 0x0000005E is one of data in Source memory, but all the data in destination memory are the same.
    And you can find that there are many 0xFFFFFFFF in a particular position we don't want, more important is that these 0xFFFFFFFF can't be rewrite manually in the memory window in CCS.

    Could you please check out my configuration and give me a advance instruction?

    Best regards

    Cesc Chou

  • Hi Gus

    I have post my problem and EDMA configuration in the reply for Mukul above.

    Could you please give me some more advice? Thank you.

    Best regards

    Cesc Chou

  • Hi Cesc

    I hope you DSP PCB to PC interface over PCI does not have any issues. If there are any PCI gotchas to look for , Gus or someone else might be able to chime in. Is this your custom board, or a TI EVM/DSK? I am assuming that since you have some success with the interface, since you said CPU initiated accesses seem to be working fine?

    I can't find something glaringly wrong in your code, but here are something you can try/confirm for me

    1} I am hoping when you change from TC0 to TC1, you did the change by finally calling the API (status = CSL_edma3HwSetup(hModule,&hwSetup);) , I didn't see that in your code snippet but I am assuming you did that. Another quick way to make sure that you don't have any software set up issue on this would be to check the DMAQNUM register for the DMA channel you are using for PCI transfers

    2) Can you also provide me the param memory for this channel, before and after the transfer. I would assume that if the transfer triggered properly , you would see a Null paramentry after transfer completion

    3) Last thing ( although I don't think this should help/make a difference), instead of ACNT=512, BCNT=1, CCNT=1 , can you try ACNT=4, BCNT= 128, CCNT=1, AB Sync, SRC/DST BIDX= ACNT , SRC/DST CIDX = ACNTxBCNT ( this should not matter).

    4) I am assuming that you have no issues with DDR2 memory, and you see the desired initialization/values in the sourceAddr buffer.

    If this doesn't help, hope to get you some more help , next week.

    Regards

    Mukul

  • Hi Mukul,

    Thank you for your suggestion. I'm sorry for replying you so late. 

    First, I did change the TC by using CSL_edma3HwSetup().

    Then, I have no issues with DDR2 memory.

    As you refer to the param memory, I can't provide this time because there is not equipments in my home:), so I will do some experiment and provide the result to you as soon as possible.

    But there is still some doubts in my head. In my system, DSP communicates with PC through a PCI bridge core--PCI 6152, when we trigger DSP's EDMA to transfer data to PC, the data is transfered to PCI bridge's buffer or to PC's real memory space though they have the same physical address from DSP side. I think this helps to understand the reason why EDMA can not work. Please explain this.

    Best regards

    Cesc

  • Cesc,

    jay chou said:
    In my system, DSP communicates with PC through a PCI bridge core--PCI 6152, when we trigger DSP's EDMA to transfer data to PC, the data is transfered to PCI bridge's buffer or to PC's real memory space though they have the same physical address from DSP side. I think this helps to understand the reason why EDMA can not work. Please explain this.

    CPU writes to PCI space would also have to go through the PCI bridge, yet those are working for you, right?  Are you suggesting there may be some performance limitation of the bridge? Could this be an issue with the bridge configuration?

    I was hoping there was a way to throttle the PCI data throughput from the DSP, but I don't see a way to do this.  The best we can do is limit the commands the DSP PCI uses when communicating with the bridge.  You can try setting the following bits to 0 in the Master Configuration Register (PCIMSTCFG): SW_MEM_RD_MULT_EN, SW_MEM_RD_LINE_EN, SW_MEM_RD_WRINV_EN.  This will force the PCI to not use memory read multiple, memory read line, and memory write-and-invalidate commands.  Not sure this will help though.

    Gus

  • Hi Mukul,

    Today I did some experiment to verify your suggestions.

    First, I exchaged srcAddr and dstAddr in the EDMA configuration code, the result was that data with start address 0x40000000(PCI master window) could be transfered to address 0xE0000000(DDR2). So I'm afraid of the data in 0x40000000 are partially read-only. Maybe the PCI bridge needs to be configured by PCI host(PC).

    Then, I changed the Acnt, Bcnt and so on into the value you adviced. Unfortunately, the problem was still there. As follows:

     address                   data

    0x40000000      0x0000005E                                                                                                                                                                                                                                                                       0x40000004      0xFFFFFFFF                                                                                                                                                                                                                                                                                                                 

    and so on....

    If I write a value(eg. 0x11111111) by PC's software--DriverWizard to memory 0xBE000000 which corresponding the address 0x4000000 in DSP PCI address. I found that all the 0x0000005E were changed into 0x11111111 and 0xFFFFFFFF were still be.

    The EDMA transfer was properly triggered, because I can watch the registers throw CCS. I could see the IER was set, and IPR was set and then cleared. Moreover, ERRDET in EDMATC1 didn't catch any error. 

    Third, I have insteaded the EDMA code into these code:
     tmpSrcAddr = (Uint32)SourceAddr;
     tmpDstAddr = 0x40000000 | (0xBE000000 & ~0xFF800000); 
      for(i = 0; i< 512; i+=4)
        {
            *((Uint32 *)tmpDstAddr) = *((Uint32 *)tmpSrcAddr);
            tmpDstAddr+=4;
            tmpSrcAddr+=4;
        }

    what a shame, still the same result. I'm afraid that the problem is not in EDMA but in the PCI bridge. What's your opinion?

    Best regards,

    Cesc 

  • Hi Gus,

    I did some test follow your instruction--cleared the bits corresponding to SW_MEM_RD_MULT_EN, SW_MEM_RD_LINE_EN, and SW_MEM_RD_WRINV_EN. But the problem still exists.

    More results are post in the replying to Mukul above, you could take them as a referrence.

    Thank you all the same.

    Best regards

    Cesc

  • Can you send a list of the values being programmed into the PCI registers?  I can review to make sure there are no configuration issues there. 

  • jay chou said:
    I'm afraid that the problem is not in EDMA but in the PCI bridge. What's your opinion?

    I tend to agree with that, based on your latest updates, I think  EDMA configuration is not the issue here. We need to focus on the PCI side of things. Gus is looking at this (and hence the request for PCI register configuration) and we have also forwarded it to a bunch of other PCI experts, if they have additional debug tips to offer.

    Hope to see this issue resolved soon.

    Regards

    Mukul

     

     

  • Hi Gus,

    There is my list of the value being programmed into the PCI registers.

    PCISTATSET 00000000
    PCISTATCLR 00000000
    PCIHINTSET 00000000
    PCIHINTCLR 00000000
    PCIBINTSET 80000000
    PCIBINTCLR 00000000
    PCIBCLKMGT 00000100
    PCIVENDEVMIR B000104C
    PCICSRMIR 02000016
    PCICLREVMIR 00000001
    PCICLINEMIR 00004008
    PCIBAR0MSK FF800008
    PCIBAR1MSK FFC00008
    PCIBAR2MSK FF800008
    PCIBAR3MSK FF800008
    PCIBAR4MSK FF800008
    PCIBAR5MSK FF800008
    PCISUBIDMIR 00000000
    PCICPBPTRMIR 00000040
    PCILGINTMIR 00000111
    PCISLVCNTL 003F0001
    PCIBAR0TRL 02C00000
    PCIBAR1TRL 01800000
    PCIBAR2TRL 02800000
    PCIBAR3TRL 80000000
    PCIBAR4TRL A0000000
    PCIBAR5TRL E0000000
    PCIBARMIR[6] BF000008
    PCIMCFGDAT 00000000
    PCIMCFGADR 00000000
    PCIMCFGCMD 80000000
    PCIMSTCFG 00000000
    PCIADDSUB[32] 00000000
    PCIVENDEVPRG B000104C
    PCICMDSTATPRG 00000000
    PCICLREVPRG 00000001
    PCISUBIDPRG 00000000
    PCIMAXLGPRG 00000000
    PCILRSTREG 00000000
    PCICFGDONE 00000001
    PCIBAR0MPRG 0FF80000
    PCIBAR1MPRG 0FFC0000
    PCIBAR2MPRG 0FF80000
    PCIBAR3MPRG 0FF80000
    PCIBAR4MPRG 0FF80000
    PCIBAR5MPRG 0FF80000
    PCIBAR0PRG 00000001
    PCIBAR1PRG 00000001
    PCIBAR2PRG 00000001
    PCIBAR3PRG 00000001
    PCIBAR4PRG 00000001
    PCIBAR5PRG 00000001
    PCIBAR0TRLPRG 00080000
    PCIBAR1TRLPRG 00180000
    PCIBAR2TRLPRG 00280000
    PCIBAR3TRLPRG 08000000
    PCIBAR4TRLPRG 0A000000
    PCIBAR5TRLPRG 0E000000
    PCIBASENPRG 0000003F

    Hopes it could help you find some problems.

    Thank you

    Best regards

    Cesc

  • Can you expand PCIBARMIR[6] and PCIADDSUB[32]?

  • I'm sorry about this matter.

    These are the explicit configuration:

    PCIBARMIR[0]  =  0xBF000008 

    PCIBARMIR[1]  =  0xBF800008

    PCIBARMIR[2]  =  0xBE800008 

    PCIBARMIR[3]  =  0xBE000008 

    PCIBARMIR[4]  =  0xBD800008 

    PCIBARMIR[5]  =  0xBD000008 

    PCIADDSUB[0] = 0xBE000000

    and other PCIADDSUBn are 0x00000000. All the registers above are configured by software.

    There is another suprising phenomenon:  After I have finished data transfering, though the result wasn't right,  I refreshed the memory wacth window repeatedly in CCS,    I found data in the 0x40000000 randomly changed. Why? This problem puzzle me a long time. Could you please give me some anwsers?

    Cesc

           

  • Based on the way you have programmed the PCI registers, your PCI master writes/reads are landing right back in the DSP.  When you write or read from 4000 0000h in DSP memory, the PCIADDSUB[0] translates that address to BE00 0000h and the PCI starts a master transaction.  Since you have PCIBARMIR[3] set to BE00 0008h, the DSP PCI recognizes that as one of its addresses and attempts to access DSP memory.  If you follow the PCIBAR3TRL and PCIBAR3MSK registers you'll see that BE00 0000h gets translated into 8000 0000h which not a supported address in the C6455 DSP memory map.

    If BE00 0000h is the correct PCI address for the memory you are trying to access, then you need to disable PCIBARMIR[3] by setting BASE3_EN = 0 in PCISLVCNTL.  This will prevent the DSP from responding to any accesses made to PCI addresses at BE00 0000h.  If BE00 0000h is not the right address, then write the correct address to PCIADDSUB[0] being careful to make sure there are no overlaps between DSP PCI addresses and the PCI addresses of any other devices on the PCI bus.

    I hope this helps.

  • Hi Gus,

    Thanks for your professional and patient.

    There are some questions I want to confirm after reading your suggestions.

    First, take a look at this which I picked out from the 645X PCI user's guide:

    Base Address         Window Size          Prefetchable           Memory Space
             0                                8MB                       Yes                        0x008 0000
             1                                4MB                        No                         0x018 0000
             2                                8MB                        No                         0x028 0000
             3                                8MB                       Yes                        0x800 0000(1)
             4                                8MB                       Yes                        0xA00 0000
             5                                8MB                       Yes                        0xE00 0000

    (1)The default value for PCI Base Address 3 (0x800 0000) is not a supported memory address range for C645x devices and
    needs to be reprogrammed before being used.

    I'm not sure that if 0x800 0000 is the same to your 8000 0000h which not a supported address in C6455. Because the address is not complete. And what's the difference between these 6 PCI Base Addresses and the 6 PCI BAR I read from PC?

    I guess what you want to tell me are: I want to configure the DSP as master, but I have programmed PCIBARMIR[3] by software, so I mislead DSP to operate in a wrong memory space that it can't support. what I have to do is to disable PCIBARMIR[3].

    Then, I want to set DSP as master, if there is no need to use slave window?

    Best regards,

    Cesc

  • Hello Gus and Mukul,

    I followed your instructions and I was successed at last! Though I can't understand the mistaken reason well, I will go on studying on it.

    Now, no words can express my appreciation to you, for your professional skills and completely patient!

    I'm so glad to see that Ti owns such employee like you!

    Thanks to Ti! Thank you! Without you I can't finish my project.

    Best regards

    sincerely

    Cesc

  • Glad to hear your problem is solved. Thanks for the kind comments.  Just to make sure your final questions don't go unanswered, here is my response...

    First some basic info:

    The PCI has two independent halfs:
    - PCI master: accepts requests from modules like the EDMA and CPU and initiates an access on the PCI bus.
    - PCI slave: accepts requests from masters on the PCI bus (such as your PC) and initiates an access inside the DSP.

    >>I'm not sure that if 0x800 0000 is the same to your 8000 0000h which not a supported address in C6455. Because the address is not complete. And what's the difference between these 6 PCI Base Addresses and the 6 PCI BAR I read from PC?

    The PCI slave supports 6 independent memory windows.  A memory window is a view into the DSP memory map.  By writing to memory window 0, for example, you are writing to DSP address 0x0080 0000 (L2 SRAM).  By reading from memory window 5, you reading from 0xE000 0000 (DSP DDR memory). 

    Each memory window is linked to a specific address in the PCI memory map through the PCI BAR registers.  For example, let's say that BAR0 has 0x3000 0000.  If the PC writes to 0x3000 0000, the PCI slave interprets that as a write to slave window 0 and translates that write to 0x0080 0000 (DSP L2 SRAM).  Note that the PCI address and DSP address for each window can be totally different, this is up to you.

    One more note, the MSK and TRL PCI registers allow you set the size and also the DSP address each DSP memory window. The default size is given in the table you provided earlier. 

    >>I guess what you want to tell me are: I want to configure the DSP as master, but I have programmed PCIBARMIR[3] by software, so I mislead DSP to operate in a wrong memory space that it can't support. what I have to do is to disable PCIBARMIR[3].

    Not exactly, but close.  Note that the problem was that you were using the PCI master to write to PCI address BE00 0000h.  The problem was that you were also programming the PCI slave (window 3) to respond to PCI address BE00 0000h.  So on one hand, the PCI master was initiating a transaction to BE00 0000h, and the independent PCI slave was responding to the same transaction. Furthermore, the window 3 was translating that address to 0x8000 0000, which is not a supported DSP address. 

    One solution was to simply disable window 3.  Another solution would have been to write a different address BAR3; one that did not have this conflict.  You used the first approach.

  • Hi Gus,

    Whether there is a strict mapping rule between the 6 slave windows and the 6 PCI BAR? For example slave window 0 can only map PCIBAR0. From your reply, I guess so.

     If DSP is set as a PCI slave, what DSP needs to do is just configure some registers to make sure the memory map right and the data transfering is PCI master's job. Am I right?  

    Best regards

    Cesc

  • jay chou said:
    Whether there is a strict mapping rule between the 6 slave windows and the 6 PCI BAR? For example slave window 0 can only map PCIBAR0. From your reply, I guess so.

    Yes, each BAR register is mapped to a specific window.  BAR0 to window 0, BAR1 to window 1, etc.

    jay chou said:
    If DSP is set as a PCI slave, what DSP needs to do is just configure some registers to make sure the memory map right and the data transfering is PCI master's job. Am I right?  

    It depends.  By default each window points to a specific DSP memory address.  If you are okay with that default mapping then there is no configuration required from the DSP side.  From the PCI side, an external PCI device must configure the DSP PCI registers, including the BAR registers.

  •  

    Hi Gus,

    Though the problem has been resolved, but I still doult this part of your reply.

    "Not exactly, but close. Note that the problem was that you were using the PCI master to write to PCI address BE00 0000h. The problem was that you were also programming the PCI slave (window 3) to respond to PCI address BE00 0000h. So on one hand, the PCI master was initiating a transaction to BE00 0000h, and the independent PCI slave was responding to the same transaction. Furthermore, the window 3 was translating that address to 0x8000 0000, which is not a supported DSP address. "

    These six PCIBARnTRL with theirs default value:

    PCIBAR0TRL 02C00000
    PCIBAR1TRL 01800000
    PCIBAR2TRL 02800000
    PCIBAR3TRL 80000000
    PCIBAR4TRL A0000000
    PCIBAR5TRL E0000000

    When I initiat a master transaction to PCI address BE00 0000h, why PCI slave can responding to it? Is it because I had programmed PCIBARMIR? But PCIBARMIR just configure the PCI base address and prefecthable etc. After all, data transaction is initiated by DSP but not the PC. How can slave back end interface response the master transaction request? Does that means DSP can write data to its own memory through PCI module?

    In another word, if I reprogrammed PCIBAR3TRL from 80000000 to any available address of DSP, if it means that when DSP initiate a data transaction to BE000000, data is transfered to DSP's own memory actually, but not PCI address I want? If I don't disable BASE3 Configuration in PCISLVCNTL, there is always a conflict between master write and slave write?

    I'm sorry to disturb you so much, but I think as a student in DSP' field, it is very important to ask why?

    Hope you not feel  bother. Thank you.

    Best regards

    Cesc

  • jay chou said:
    When I initiat a master transaction to PCI address BE00 0000h, why PCI slave can responding to it? Is it because I had programmed PCIBARMIR?

    Yes, because you have programmed BE00 0000h in PCIBARMIR3, the PCI slave will respond to the PCI master transaction.

    jay chou said:
    But PCIBARMIR just configure the PCI base address and prefecthable etc. After all, data transaction is initiated by DSP but not the PC. How can slave back end interface response the master transaction request? Does that means DSP can write data to its own memory through PCI module?

    Apparently so, although I had never tried a "loopback" case like this.  I had always made sure that the PCI master wrote to PCI addresses not monitored by the PCI slave.

    jay chou said:
    In another word, if I reprogrammed PCIBAR3TRL from 80000000 to any available address of DSP, if it means that when DSP initiate a data transaction to BE000000, data is transfered to DSP's own memory actually, but not PCI address I want?

    Yes.

    jay chou said:
    If I don't disable BASE3 Configuration in PCISLVCNTL, there is always a conflict between master write and slave write?

    No.  If you don't read/write to addresses monitored by the PCI slave, the "loopback" condition will not be there.  You need to be careful to NOT assign PCI addresses to the PCI slave that are used by other PCI devices in your system.  If in your system the PC was assigned BE00 0000h, the the DSP PCI slave BAR3 register should never have been configured with BE00 0000h.

     

     

     

  • Hi Gus, I have to say this website is very hard to link.:) Maybe for its huge throughput. Could you please tell me in which condition should I configure PCIBARMIR? Since PCIBAR is programmed by PCI host, why there are a set of mirror registers? Or I have some misunderstanding. Even if sets DSP as slave, we only need to configure PCIBARTRL and PCIBARMSK, Because DSP can not control the assignment of the six BARs' memory space. Waiting for your reply sincerely. Best regards Cesc
  • The BARMIR registers are there so that the application running on the DSP can know what configuration was implemented by the PCI host.  Also, in some embedded systems the DSP itself acts as the PCI host, so having direct access to its own PCI registers is advantageous. 

    You are absolutely right in saying that since your PCI host is writing to the BAR registers, you do not need to configure them through the BARMIR registers.  You only need to configure the MSK and TRL registers as you point out.

  • Hi Gus,

    It's long time not to contact with you. Wish you everything is fine.

    This time I met some problems about using TCP2 in C6455. That problem is when I ran a program on simulator, the TCPIC registers are writerable, but when I do it on a DSK, some of TCPIC can not be rewrite by EDMA nor memory write directly. Do you have some experience about it?

    Waiting for your replys sincerely.

    Best regards

    Cesc

     

  • Since this is a new question, I am starting a new thread here:

    http://e2e.ti.com/support/dsp/tms320c6000_high_performance_dsps/f/112/p/43073/150248.aspx#150248