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 executing DioLib test: testDIO_edmaStreamLsu

Afte We are attempting to execute the testDIO_edmaStreamLsu example from DioLib. In this example, test case 0 is supposed to perform "EDMA-initiated directIO long (>4KBytes) streaming write and read operations with interrupt completion mechanism and a possible doorbell notification at the slave."

This test case calls DIO_streamingReq to perform the DIO send,  after which it calls  asm(" IDLE");, which according to a comment is to wait for an EDMA interrupt.
After IDLE, the example code calls DIO_getOpCompCode to check the completion code of the Srio transaction

First off, the IDLE is never passed. This may be due to commented out interrupt code in DioLib, but by commenting out the IDLE, we can get to the completion code using the debugger, which always fails regardless of how long we wait. When this send is performed we can see data received by the other Srio device, but only 512 bytes, not the 5120 bytes. And of course, since the transaction  appears to never completes, no doorbells are generated.

We are executing on 2 TMDSEVM6457 evaluation boards with lane 1 of Srio connected between the 2 boards.

Code was commented out of DioLib following the CSL example  testDIO_edmaStreamLsu. this was done just to get the Srio device to report initialized in the SP0_ERR_STAT register.

Independent of the state on interrupt enables on the device, should'nt the send still send all 5120 bytes. We are using the change of colors in the memory view to determine the number of bytes transfer, and have verified the contents of the first 16 bytes, but not the entire 512 bytes.

Do you have any idea what we should be looking for to correct this?

Bob Coburn



  • Bob,

    The IDLE is used to synchronize the activity. The intent is to wait there until it is known that you can continue.

    Why did you have to comment out the interrupt code? Can this be implemented in a polling wait loop?

    The fact that the completion code fails all the time implies that the first part, the transfers, are not happening or are not signalling completion. The fact that only 512 bytes have gone out could mean that the EDMA event connections are not set right. Can you tell from the EDMA register bits (EMR, IPR, SEC) what the operation status is? And also what the DMA channels' PARAM registers have changed to?

    Regards,
    RandyP

  • Bob,

    Can you dump the err_stat register for the port you are trying to use?  I'd like to know if there are any physical layer issues here.  Set a breakpoint and make sure port_ok is set and input/output errored stopped states are cleared.

    Also, when you program the EDMA, try to get a simple case working first.  For example, program just one EDMA entry to cause SRIO to transfer 4096B.  This would create 16 packets of 256B payloads.  Does this work for you?  If so, then move to a EDMA linking example.

    Regards,

    Travis

  • Upon Initialization, my transmitter contains 0x00020002 (PORT_OK & OUTPUT_ERROR_ENC)

    I had not previously noticeded that the  function DIO_streamingReq is returning an invalid value of 0xA3A3 and looking at the source code, this is not a possibility unles my stack is corrupted.

    Without clearing the error, I reran with the suggested size of of 4096, and everything stayed the same, but the return code changed to 0xA3A2 

  • Can you check both EVM err_stat on TX and RX?  Or just implement the SW error recovery process before starting any actual edma or SRIO transfers.  This is discussed in Appendix B of http://www.ti.com/lit/ug/sprugk4d/sprugk4d.pdf.  Let me know what you get when you try to just do a single EDMA transaction too.

    Regards,

    Travis

  • Travis,

    What do you mean by EVM err_stat. We did check the SP0_ERR_STAT on both sides. The receiver was 0x00000002

    Regards,

    Bob

  • We implemented the error clearing you suggested and performed a send with 4096 bytes when the ERR_STAT register only indicated port_OK.

    My previous statement about the value returned by DIO_streamingReq was incorrect. the actual function being called is DIO_rawEdmaLsuSetup so the status I was looking at was uninitalized.

    The DIO_getOpCompCode still indicates that the transaction in not completing  e.g. !=CSL_SRIO_TRANS_NO_ERR

    Attempting to view the data through the debugger is unreliable. We were using the color change in the memory window to verify the amout of data receive, which we no know to be unreliable. It appears we are getting more data than we thought. Our next step is to  programatically read the data and verify what is received that way.  

    I'm stil concerned about the completion code, since the plan is for the sender to send a doorbell when the reansaction completes

     

    Regards,

    Bob Coburn

  • Good, that is what I meant.  So it seems the physical layer is ok then.  Need to find out if you can send one multi-packet transaction using the edma.

    Regards,

    Travis

  • Can you use the memory browser to read the LSU CC code directly and tell me what the exact completion code is?

    Regards,

    travis

  • Register LSU0_REG6 contained 0xE, the rest of the LSUn_REG6 contained 0. Not sure what the 0xE means since the documentation says this is "

    Transaction complete, packet not sent due to unavailable outbound credit at given priority. We ran this on a 4096 packet and implemented code on the receiver to verify the data and the receive verified all 4096 bytes. Then we incremented the packet back to the original 5120, but our verification code only validated 4096.

    Bob Coburn

  • Bob,

    If you received a CC=0b111, then all or part of the transfer wasn't sent at all.  I'm not sure how you could verify the payload on the RX side, if you received this CC.  Can you dump the per_set_cntl and per_set_cntl1 registers?

    Regards,

    Travis

  • Travis,

    per_set_cntl: 0x0D053940

    per_set_cntl1: 0x01010101

    Thanks,

    Ashley

  • I don't see anything wrong with those values, although i've never really used anything other than per_set_cntl1=0x00000000.  A couple things, let's make sure the port-writes are turned off during srio initialization:

    make sure bit 27 of RIO_SP_IP_MODE = 1, RIO_ERR_EN = 0x00000000, RIO_SPn_RATE_EN = 0x00000000.

    Also, what is SP_IP_MODE[31:30] set to?  Based on your answer above, it needs to be 0b01.

    Travis

  • I was able to get a CSL_SRIO_TRANS_NO_ERR completion code from the DMA and the EDMA interrupt is dispatch and received by the asm(" IDLE"). However, I am not receiving/processing the expected doorbell after the SWrite, nor can I find in the code when the doorbell is supposed to be triggered. I can see that there are also dbell_LsuNonStreaming_isr, lsu_isr and error_cppi_isr. Should any of these have been triggered as well?

     

    Thanks,

    Ashley

     

  • Ashley,

    What did you change to get past the err CC?  I'll have to look into the doorbell question.

    Regards,

    Travis

  • Unfortunately, I think I spoke too soon. It seem it only gets a successful CC idf the number of bytes is less that 4096. 4096 and over return the the err CC.

    Initialy our code ran with the following values:

    RIO_SP_IP_MODE = 0x4D000000

    ERR_EN = 0x8DC00000

    SPn_RATE_EN = 0x00000009

    Changing SPn_RATE_EN and ERR_EN  to 0x0 did not change functionality. Still only sends up to 4096 bytes and returns err CC.

    Were you able to find where the doorbell is sent after successful write? Let me know if there is anything I could provide to help, I am under a tight schedule.

     

    Thanks,

    Ashley

  • I noticed that later in main.c the in code for the C6474 multistream the logic surround the DIO_getOpCompCode is a while loop instead of an if statement.

    Code for C6457:

     if (cslStatus = DIO_getOpCompCode(&writeReqObj[testIndex]) != CSL_SRIO_TRANS_NO_ERR)
    {

    printf("\t Transaction failed \n");
    return(1);

    }

    Code for the C6474:

    while( (DIO_getOpCompCode(&writeReqObj[0]) != CSL_SRIO_TRANS_NO_ERR) ||
              (DIO_getOpCompCode(&writeReqObj[1]) != CSL_SRIO_TRANS_NO_ERR) )
    {
                    RIO_waitForHw(1000);
                    if (DIO_getOpCompCode(&writeReqObj[0]) == CSL_SRIO_UNAVAILABLE_OUTBOUND_CR)
           DIO_sendLeftStreamingCmds(&srioObj,testObjTab[0].sNum);
                    if (DIO_getOpCompCode(&writeReqObj[1]) == CSL_SRIO_UNAVAILABLE_OUTBOUND_CR)
           DIO_sendLeftStreamingCmds(&srioObj,testObjTab[1].sNum);
    }

    Replacing the if statement in the C6457 with a similar while loop:

    while(DIO_getOpCompCode(&writeReqObj[testIndex]) != CSL_SRIO_TRANS_NO_ERR )
    {

     RIO_waitForHw(1000);
     if (DIO_getOpCompCode(&writeReqObj[testIndex]) == CSL_SRIO_UNAVAILABLE_OUTBOUND_CR)
     {
      DIO_sendLeftStreamingCmds(&srioObj,testObjTab[testIndex].sNum);
      printf("Sending remaining bytes\n");
     }

    }

    Sends allows the program to transfer 5120 bytes sucessfully. However, from what I can tell, there is still no doorbell. This causes the program to get stuck in this loop waiting to sync with the slave:

    if (testObjTab[testIndex].opNotifier == DIO_NOTIFY_DOORBELL)
    {

     volatile Uint32 check = 1;

     /* sync with slave */
     while (check)
     {
      Uint32 bellIndx;
      for (bellIndx = 0; bellIndx < 3; bellIndx++)
      {
       volatile Uint32 gie;
       gie = _disable_interrupts();
       if (ringingBell[bellIndx] != 0)
       {
        ringingBell[bellIndx] = 0;
        _restore_interrupts(gie);
        check = 0;
       }
       else
       {
        _restore_interrupts(gie);
       }
      }
     }
    }

  • Hi Ashley,

    The following are the parameters for the first transfer in testDIO_edmaStreamLsu project:

    {   
          "SWrite0",
          RIO_FTYPE_SWRITE,
          (Uint8)RIO_SWRITE_TTYPE_DEFAULT,
          RIO_PACKET_PRIO_MEDIUM,
          (Uint16)0xBEEF,         /* DestId */
          (Uint32) 5120,         /* NumBytes */   
          #ifdef CHIP_C6455   
          (Uint32*)0x904000,    /* RapidIO destination addr - Slave DSP (0x900000 and beyond (L2/DDR2))*/
          #endif
          #ifdef CHIP_C6474   
          (Uint32*)0x12800000,  /* local L2 of core 2 */
          #endif
          DIO_NOTIFY_DOORBELL,  /* Notify destination with dbell when numBytes were sent */
          0x0001,               /* Dbell info number */
          NULL,
          NULL,    
          0,                     /* raw_lsu_setup */
          #ifdef CHIP_C6455
          RIO_EDMA_STREAM_0      /* EDMA stream number */   
          #else // CHIP_C6474
          RIO_EDMA_STREAM_0      /* EDMA stream number */   
          #endif
        }

    In the above case, we are performing a SWRITE of 5120 bytes (for SWRITE we should always make sure the byte count is double-word aligned, if required to transfer a non double-word aligned payload use NWRITE). As the byte count > 4096 and DIO_NOTIFY_DOORBELL is enabled, the LSU register set will be programmed by the EDMA. Only if byte count <= 4096 and DIO_NOTIFY_NONE, then CPU will program the LSU register set. The following is the sequence and the break up of DIO transactions performed by EDMA:

      1) SWRITE of 4096 bytes

      2) SWRITE of 24 bytes

      3) Send doorbell no 1 with doorbell info = 0x1

    On the TX side, if all the above three steps are successful, the EDMA final transfer completion interrupt will be triggered. This can be verified by putting a break point in edmaIsr(). The final EDMA interrupt will not trigger, even if any one of the above 3 DIO transcations fail with a error completion code. If we do not get the final EDMA interrupt, then we need to debug further into this issue.

    On the RX side, you can use the testDIO_dbell (slave) project for receiving the doorbells from the TX. The dbell_LsuNonStreaming_isr() is called whenever a doorbell packet is received. After acknowledging the doorbell, the RX destination memory should be validated for the correctness of the SWRITE transfer between two C6457 EVMs.   

  • Ashley,

    Sorry. I missed your last comment and posted my response based on your last comment on the previous page.

    Great. The final EDMA interrupt is successfully received and the doorbell with doorbell info 0x1 should have been successfully sent to the slave. On the slave side, you can check if the dbell_LsuNonStreaming_isr() is called. It would be helpful, if you could share the value of DOORBELL0_ICSR(offset 0x200) register on the slave side.