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.

c6745 SPI-EDMA question

Hello,

I've spent some time with an irritating problem - not a showstopper, I can live with it - but irritating!!! Main question is that how to finalize SPI/EDMA transfer frame in a controlled way. EDMA-finishing interrupt server is the main problem

Below is the interrupt server code and below that scope view where blu-SIMO, grn-CLK, red-EdmaIsr and yel-Edma3CCErrHandlerIsr. TX- int is not interesting to me because RX is not completed yet that time- so I would only need RX-int (EDMA3_CHA_SPI0_RX) . I've tried to get rid of the TX-int (EDMA3_CHA_SPI0_TX) but not managed, I need to acknowledge it somehow, below is the minimum I've found. . I've tried to get rid of the Edma3CCErrHandlerIsr after every TX-int but not managed. 

I can let the Edma3CCErrHandlerIsr to shoot these extra interrupts but they are waste of resources and I would like to know if this problem will one day stop the SPI-EDMA totally. 

No-one but these IR- servers is touching SPI in the mean time, the length of the data does not change anything. All flags have been deactivated before lounching the xfer, if not properly would cause this problem earlier than the last byte??

Thank you and best regards,

Risto

void EdmaIsr(void)
{
   UL ulIPR;

   GPIOPinWrite(SOC_GPIO_0_REGS, LED_3_IO_NUM, 1);

    ulIPR = EDMA3GetIntrStatus(SOC_EDMA30CC_0_REGS);

   IntEventClear(SYS_INT_EDMA3_0_CC0_INT1);

   if(ulIPR & (1<<EDMA3_CHA_SPI0_TX))
       EDMA3ClrIntr(SOC_EDMA30CC_0_REGS, EDMA3_CHA_SPI0_TX);

   if(ulIPR & (1<<EDMA3_CHA_SPI0_RX))
   {
      SPIIntDisable(SOC_SPI_0_REGS, SPI_DMA_REQUEST_ENA_INT);
      g_poMessageManager->IntServerSpiEdma();
   }

   GPIOPinWrite(SOC_GPIO_0_REGS, LED_3_IO_NUM, 0);

}

void Edma3CCErrHandlerIsr(void)
{
   UI uiCCerrStat,
   uiEventErrStat;
   GPIOPinWrite(SOC_GPIO_0_REGS, LED_2_IO_NUM, 1);

   g_uiEdmaErrors++;

   IntEventClear(SYS_INT_EDMA3_0_CC0_ERRINT);

   // EDMA3CC_CCERR - page 526
   uiCCerrStat = EDMA3GetCCErrStatus(SOC_EDMA30CC_0_REGS);
   // EDMA3CC_EMR - Event Missed Register, page 522
   uiEventErrStat = EDMA3GetErrIntrStatus(SOC_EDMA30CC_0_REGS); // debug
   EDMA3ClrMissEvt(SOC_EDMA30CC_0_REGS, EDMA3_CHA_SPI0_TX);
   uiEventErrStat = EDMA3GetErrIntrStatus(SOC_EDMA30CC_0_REGS); // debug
   GPIOPinWrite(SOC_GPIO_0_REGS, LED_2_IO_NUM, 0);

}

blu-SIMO,

grn-CLK,

red-EdmaIsr and

yel-Edma3CCErrHandlerIsr

  • Risto,

    It will make the job easier for your readers if you list your signals in the same order as they are shown. The colors make that arbitrary, but quick conceptualization is easier with obvious ordering.

    Try slowing down your SPI clock to see if the problem is related to relative speeds.

    It is not clear what you are trying to do in the EDMA ISR with your Rx code. You clear the SPI interrupt instead of the EDMA IPR interrupt bit.

    You should not be getting any EDMA3CC error interrupts. This needs to be pursued to get rid of those. The speed test will be very useful.

    Also, please show your DMA channel PARAM initialization code.

    Regards,
    RandyP

  • Hi,

    I would like to open this case again if OK.

    I faced another EDMA -problem which could be related to this earlier one, which I simply solved by removing Error Isr (Edma3CCErrHandlerIsr), which off course was not a hygienic solution but the only solution that time to proceed. Error seems to be caused by "Event miss" and it is not related to SPI- clock speed. 

    I did some additional testing with starterware code (ATTACHED) and recognized that it was also generating Error interrupts. I transferred spiEdma.c to my project- template to fit it to my custom environment; I think project settings can not influence this Error Isr -problem??

    My acute problem is in EDMA -reinitialisation. I need EDMA in my primary booter (loaded from EEPROM) and in my firmware. Booter will initialize SPI/EDMA and uppload firmware from FLASH. In firmware EDMA reinitialization does not work even if I try to totally kill EDMA and SPI. I use following piece of code for killing:

    SPIReset(SOC_SPI_1_REGS);
    EDMA3Deinit(SOC_EDMA30CC_0_REGS,0);
    EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_SPI1_TX, EDMA3_TRIG_MODE_EVENT, EDMA3_CHA_SPI1_TX, 0);
    EDMA3FreeChannel(SOC_EDMA30CC_0_REGS, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_SPI1_RX, EDMA3_TRIG_MODE_EVENT, EDMA3_CHA_SPI1_RX, 0);

    Could this reinitialization problem be caused by the Edma3CCErrHandlerIsr? Can you propose some "cold start level" de/reinitialization of EDMA?

    Best Regards,

    Risto

  • Risto,

    You marked my post above as being the Answer to your question. It is not clear why you did that, unless it led to a resolution.

    It would be best to have this new question posted to a new thread with an appropriate new title, but I will leave that to you.

    Risto Hedman said:
    Error seems to be caused by "Event miss" and it is not related to SPI- clock speed. 

    Ignoring an Event Missed error can be catastrophic. You have not explained why you think it is not related to SPI clock speed. The combination of removing the error handler ISR for illogical reasons, ignoring the underlying error, and expecting the system to work well afterwards does not seem likely to lead to success, to me at least.

    Risto Hedman said:
    Could this reinitialization problem be caused by the Edma3CCErrHandlerIsr? Can you propose some "cold start level" de/reinitialization of EDMA?

    I am confused how this problem could be caused by the ISR that you removed. For a cold-start, Here is some code I found for an older EDMA3-based device. A lot of this may not be relevant to the implementation of EDMA3 in the C6745, but you can delete the parts that write to registers that do not exist. I made a couple of changes to make it more robust in the EMR/SER portion, the alternative to writing to SECR/H 4 times is to write to it until SER stays cleared; the read-write process can be slower than writing 4 times although not likely in this case - I just always do it this way out of habit. This code was written for the C6474 and the addresses and other code will need to be changed to work with your device. If you choose to use this, please re-post your fixed code for future readers (I used the </> icon at the far right of the edit icons for inserting code).

    /* use to read / write 32-bit memory mapped register */
    #define LOCAL_REG32(addr) *(volatile unsigned int *)(addr)
    
        /* zero out all PaRAM */
        memset((void*)LOCAL_EDMA_PARAM_BASE, 0x00, 256*32);
    
        /* clear any pending EDMA events */
        LOCAL_REG32(0x02A01008 /* ECR  */) = 0xFFFFFFFF;
        LOCAL_REG32(0x02A0100C /* ECRH */) = 0xFFFFFFFF;
    
        /* clear any pending secondary events */
        LOCAL_REG32(0x02A01040 /*SECR  */) = 0xFFFFFFFF;
        LOCAL_REG32(0x02A01044 /*SECRH */) = 0xFFFFFFFF;
    
        /* clear any pending secondary events */
        LOCAL_REG32(0x02A01040 /*SECR  */) = 0xFFFFFFFF;
        LOCAL_REG32(0x02A01044 /*SECRH */) = 0xFFFFFFFF;
    
        /* clear any pending secondary events */
        LOCAL_REG32(0x02A01040 /*SECR  */) = 0xFFFFFFFF;
        LOCAL_REG32(0x02A01044 /*SECRH */) = 0xFFFFFFFF;
    
        /* clear any pending secondary events */
        LOCAL_REG32(0x02A01040 /*SECR  */) = 0xFFFFFFFF;
        LOCAL_REG32(0x02A01044 /*SECRH */) = 0xFFFFFFFF;
    
        /* clear any missed EDMA events */
        LOCAL_REG32(0x02A00308 /* EMCR  */) = 0xFFFFFFFF;
        LOCAL_REG32(0x02A0030C /* EMCRH */) = 0xFFFFFFFF;
    
        /* disable EDMA interrupts */
        LOCAL_REG32(0x02A01058 /* IECR  */) = 0xFFFFFFFF;
        LOCAL_REG32(0x02A0105C /* IECRH */) = 0xFFFFFFFF;
    
        /* clear anny pending EDMA interrupts */
        LOCAL_REG32(0x02A01070 /* ICR  */) = 0xFFFFFFFF;
        LOCAL_REG32(0x02A01074 /* ICRH */) = 0xFFFFFFFF;
    
        /* clear any missed QDMA events */
        LOCAL_REG32(0x02A00310 /* QEMCR */) = 0xFFFFFFFF;
    
        /* Clear any pending QDMA events */
        LOCAL_REG32(0x02A01088 /* QEECR */) = 0xFFFFFFFF;
    
        /* Clear any pending QDMA secondary events */
        LOCAL_REG32(0x02A01094 /* QSECR */) = 0xFFFFFFFF;
    
        /* Clear any pending errors in the EDMA3CC error register */
        LOCAL_REG32(0x02A0031C /*CCERRCLR */) = 0xFFFFFFFF;
    
        /* set default channel PaRAM mapping */
        for (chan=0; chan<64; chan++) {
          LOCAL_REG32(0x02A00200 + 4 * chan) = 0x02A04000 + 32*chan;
        };
    
        /* program the region access registers for region 0 */
        LOCAL_REG32(0x02A00340 /* DRAE0  */) = 0x000FFFFF;
        LOCAL_REG32(0x02A00344 /* DRAEH0 */) = 0x00000000;
    
        /* program the region access registers for region 1 */
        LOCAL_REG32(0x02A00348 /* DRAE1  */) = 0xFFF00000;
        LOCAL_REG32(0x02A0034C /* DRAEH1 */) = 0x000000FF;
    
        /* program the region access registers for region 2 */
        LOCAL_REG32(0x02A00350 /* DRAE2  */) = 0x00000000;
        LOCAL_REG32(0x02A00354 /* DRAEH2 */) = 0x0FFFFF00;
    
        /* program the region access registers for region 3 */
        LOCAL_REG32(0x02A00358 /* DRAE3  */) = 0x00000000;
        LOCAL_REG32(0x02A0035C /* DRAEH3 */) = 0x00000000;
    
        /* program the region access registers for region 4 */
        LOCAL_REG32(0x02A00360 /* DRAE4  */) = 0x00000000;
        LOCAL_REG32(0x02A00364 /* DRAEH4 */) = 0x00000000;
    
        /* program the region access registers for region 5 */
        LOCAL_REG32(0x02A00368 /* DRAE5  */) = 0x00000000;
        LOCAL_REG32(0x02A0036C /* DRAEH5 */) = 0x00000000;
    
        /* program the region access registers for region 6 */
        LOCAL_REG32(0x02A00370 /* DRAE6  */) = 0x00000000;
        LOCAL_REG32(0x02A00374 /* DRAEH6 */) = 0x00000000;
    
        /* program the region access registers for region 7 */
        LOCAL_REG32(0x02A00378 /* DRAE7  */) = 0x00000000;
        LOCAL_REG32(0x02A0037C /* DRAEH7 */) = 0x00000000;
    

    Regards,
    RandyP

  • Hi Randy,

    I did some additional tests with SPI-EDMA. I dropped SPI-CLK to ~800kHz. Below is a scope screen, where

    BLUE: SPI-CLK

    RED: RX-INT

    GREEN: TX-INT

    YELLOW: EDMA-ERR-INT

    UPPER figure:Transfer complete interrupt enable.

    LOWER figure: Intermediate transfer completion interrupt enable.

    In both figures  TX-bCnt=RX-bCnt=7

    When transmission of 7th byte starts, an ERR will occur caused by "Null PaRAM set" leading to a missed event - I believe (as in http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/221143.aspx)

    Why does it come after 6th, one byte is missing? If TX-bCnt=7 and RX-bCnt=5 the error will not occur but data will be nonsense as CS- timing will not match. With self-link ERR could be removed, but I think TX data would not  then be right: the 7th byte out would actually be 1st??

    risto

  • Hi,

    I linked dummy PaRAM set to TX-PaRAM set and it seems to work, data 1,2,3,4,5,6,7 goes right and EDMA-ERR does not occur, so from my side asction is closed if you don't want to comment?

    risto