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.

Help on Dm368 SPI slave driver

Hi,everyone,

We now met some problems in SPI comm between DM368 and DM6437.In our design,we used the DM6437 for Intelligent Video Analysising and the DM368 for encoding.The DM6437 will report the IVA info to the DM368 frequently.So,for easy comm and simplify the comm protocal,we use the DM6437 as the SPI master while the DM368 as slave.

The DM6437 's Mcbsp1 port is used in SPI master mode to comm with DM368's SPI,and the Mcbsp0 port is conected with a SPI flash.

 

We use EDMA to serve the mcbsp and SPI port in the 2 processors.

 

Because the DM368 also need to initiate a SPI transfer for IVA command,we use 2 GPIOs for handshaking in the communication.

 

The figures below is a complete proces routine for DM368 initiate a SPI transfer.

 

 

 

 

All the writing and reading operation timing is as the upper figure showing.

 

 

For some limitations in DM6437 sillicon errata,we eliminate all the L2SRAM edma in our dm6437 code and the MCBSP  buffer is located at the L1DRAM on the DM6437.

The DM368's spi driver is modified based on the original SPI master driver in the ti-davinci linux kernel.

 

Now,the problem is:

If only let the DM6437 sending IVA info to DM368 while DM368 not initiate a SPI tranfer such as for IVA config or hearbeating,the SPI comm seemed not has any problems.

 

But if the DM368 frequently initiate a SPI tranfer such as for heartbeating with the DM6437,the spi comm will block very soon.We check the debug info at the moment and find the DM6437 finished sending the BUS grant CMD to DM368 and blocked at checking if the DM368 is ready for writing,but the DM368 not recevied enough bytes so it blocked at CMD rcving ,then all the operation blocked.

We read out the DM368's EDMA params regs served for SPI rcving  and found the the A_B_CNT reg show the BCnt is not 0.We setting the EDMA as A sync and the BCNT is setted to be FIXED len before start EDMA .So if the BCNT is not 0,it must mean the EDMA has not finished  rcving the FIXED len bytes data.

From the DM6437 side, we can seem the LOG_printf in EDMA event miss error interrupt,but the event missing is not in accord with the DM368 initiating spi transfer.I mean it's not everytime the DM368 initiate a SPI transfer a event miss in DM6437 will rising.It seemed the event miss not caused the EDMA loss data.

 

 

1.  Pls give me some advice how to debug this issue.What condition can cause the DM368 loss EDMA data?DM368's EDMA event miss? I will check it.

 

     Does the DM368 has the limitaiton in the SPI transfer as the DM6437 errata showing:

 

     2.1.2 Serial Port (McASP, McBSP) Transfers Should be Buffered in Internal Memory

 

     We now use DDR as the SPI buffer in the linux driver.

2.  Should we use the ARM internal ram for it?How to use  it?the internal 32K ram? remapping?
 

 

 

2010-12-15


gxf 

  • All,

     

    I have some new information:

     

     

    Some more info:

    1.

    I add some debug code in dma.c (application\src\ti-davinci\arch\arm\plat-davinci) to check if the DSP has EDMA event lost when can't read enough bytes.

     

    static irqreturn_t dma_ccerr_handler(int irq, void *dev_id,
             struct pt_regs *regs)
    {
     unsigned int mapped_tcc = 0;

     

     if (!(dma_read(EDMA_EMR) || dma_read(EDMA_EMRH) ||
           dma_read(EDMA_QEMR) || dma_read(EDMA_CCERR)))
      return IRQ_NONE;

     

     while (1) {
      u32 status_emr = dma_read(EDMA_EMR);
      u32 status_emrh = dma_read(EDMA_EMRH);
      u32 status_qemr = dma_read(EDMA_QEMR);
      u32 status_ccerr = dma_read(EDMA_CCERR);
      int lch, i;

     

      if (!(status_emr || status_emrh || status_qemr || status_ccerr))
       break;

     

      lch = 0;
      while (status_emr) {
                printk("\n\n\nEDMA event lost!\n\n\n");
       i = ffs(status_emr);
       lch += i;
       /* Clear the corresponding EMR bits */
       SET_REG_VAL(1 << (lch - 1), EDMA_EMCR);
       /* Clear any SER */
       SET_REG_VAL(1 << (lch - 1), EDMA_SH_SECR(0));

     

       mapped_tcc = edma_dma_ch_tcc_mapping[lch - 1];
       dma_handle_cb(mapped_tcc, DMA_CC_ERROR);
       status_emr >>= i;
      }

     

      lch = 32;
      while (status_emrh) {
                printk("\n\n\nEDMA eventh lost!\n\n\n");
       i = ffs(status_emrh);
       lch += i;
       /* Clear the corresponding IPR bits */
       SET_REG_VAL(1 << (lch - 33), EDMA_EMCRH);
       /* Clear any SER */
       SET_REG_VAL(1 << (lch - 33), EDMA_SH_SECRH(0));

     

       mapped_tcc = edma_dma_ch_tcc_mapping[lch - 1];
       dma_handle_cb(mapped_tcc, DMA_CC_ERROR);
       status_emrh >>= i;
      }

     

      lch = 0;
      while (status_qemr) {
                printk("\n\n\nQEDMA event lost!\n\n\n");           
       i = ffs(status_qemr);
       lch += i;
       /* Clear the corresponding IPR bits */
       SET_REG_VAL(1 << (lch - 1), EDMA_QEMCR);
       SET_REG_VAL(1 << (lch - 1), EDMA_SH_QSECR(0));

     

       mapped_tcc = edma_qdma_ch_tcc_mapping[lch - 1];
       dma_handle_cb(mapped_tcc, QDMA_EVT_MISS_ERROR);
       status_qemr >>= i;
      }

     


      lch = 0;
      while (status_ccerr) {
                printk("\n\n\nDMA status_ccerr!\n\n\n");           
       i = ffs(status_ccerr);
       lch += i;
       /* Clear the corresponding IPR bits */
       SET_REG_VAL(1 << (lch - 1), EDMA_CCERRCLR);
       status_ccerr >>= i;
      }
     }
     dma_write(0x1, EDMA_EEVAL);

     

     return IRQ_HANDLED;
    }

     

     

    Unfortunately,not debug info be printed out when DM368 blocked on SPI reading i.e. NOT edma event lost caused the DSP blocking.

     

    2.

    I print the spi receive buffer when the DM368 blocking and find the data in the buffer are all 0!

     

    And even in the normal receiving, we can see the DM368 often lost the first byte.We add some dummy bytes before the real data and

    at the tail of the real data,so we still can run well at this moment.

     

    From the logic analyser,we can see the data be sending on the line from DM6437 is correct.So it's DM368 who  lost data!

     

     

    The below is some debug info:


    [42]:[53]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:!!!!!
    (53:)(0:)(0:)(14:)(0:)(0:)(0:)(9:)(0:)(0:)(0:)(49:)(50:)(4e:)(43:)(0:)
    i = 15
    receive ack
    begin write
    write finished !
    waiting for recieve buflen c00...
    (53:)(0:)(0:)(14:)(0:)(0:)(0:)(9:)(0:)(0:)(0:)(49:)(50:)(4e:)(43:)(0:)
    i = 15
    receive ack
    begin write
    write finished !
    waiting for recieve buflen c00...
    [42]:[53]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:!!!!!
    (53:)(0:)(0:)(14:)(0:)(0:)(0:)(9:)(0:)(0:)(0:)(49:)(50:)(4e:)(43:)(0:)
    i = 15
    receive ack
    begin write
    write finished !
    waiting for recieve buflen c00...
    (53:)(0:)(0:)(14:)(0:)(0:)(0:)(9:)(0:)(0:)(0:)(49:)(50:)(4e:)(43:)(0:)

     

     

     

     

    You can see,the correct data is 42:53...,but there are many times the first '42' is lost.

     

    When blocking:

     

    (53:)(0:)(0:)(19:)(0:)(0:)(0:)(9:)(0:)(0:)(0:)(49:)(50:)(4e:)(43:)(0:)
    i = 15
    receive bscp packet,length = 9
    waiting for recieve buflen c00...
    [0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:!!!!!
    [0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:!!!!!
    [0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:!!!!!
    [0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:!!!!!
    [0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:[0]:!!!!!

     

     

    All the data in the rcv buffer is 0!

     

    It seemed the SPI port not work!

    2010-12-15