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.

EMIF16 FIFO question.

I am tying the C6678's EMIF16 bus to a USB controller chip for data transfers between the DSP and the PC.  I have working hardware and code, successfully transferring data.

My USB device needs to have a signal toggle with the last word of data whenever the data packet being sent is less than 512 bytes.  To handle this, I have the following code segment (signal I need to toggle is on GPIO_0):

for (count = 0u; count < (len / 2) - 1; count++)
 *usbIOptr = ptr [count];
gpRegs->BANK_REGISTERS [0].OUT_DATA &= ~0x01;
*usbIOptr = ptr [count];
gpRegs->BANK_REGISTERS [0].OUT_DATA |= 0x01;

 

My problem is that the loop seems to complete before the data is actually sent out the EMIF16 interface and my signal is toggling half way through.  I'm guessing the EMIF16 interface has some sort of a FIFO that is being loaded by my loop, then sent out the actual interface underneath my code's nose.  I need to be able to synchronize my signal toggle with the last word being sent out the interface.  

I can't seem to find anything on the EMIF that suggests a "FIFO empty" type status flag.  Is there a way to monitor the EMIF sub-system and know when it has completed the transfer? 

  • I hope you've declared the registers gpRegs, usbIOptr using volatile type qualifier. Also there are these address cacheable? If so, can you try disabling data cache and see?

  • Yes, the two variables are declared using the volatile type qualifier.

    volatile CSL_GpioRegs *gpRegs = (CSL_GpioRegs *) 0x02320000;
    volatile uint16_t *usbIOptr = (volatile uint16_t *) 0x74000000;

    gpRegs points to the C6678 GPIO registers.  usbIOptr points to the C6678 EMIF16 CS3 data space.

    I didn't think either area was cacheable.

  • Can you disable the global d-cache and try? Before that I have one more question? Is this the actual code or you've just copied some relevant portion of the code? 

    Andrew Giusti said:
    for (count = 0u; count < (len / 2) - 1; count++)
     *usbIOptr = ptr [count];
    gpRegs->BANK_REGISTERS [0].OUT_DATA &= ~0x01;
    *usbIOptr = ptr [count];
    gpRegs->BANK_REGISTERS [0].OUT_DATA |= 0x01;

    I feel that you should have written the code like this. Correct me if I'm wrong.

    int flag = 0;
    for (count = 0u; count < (len / 2) - 1; count++)
    {
        *usbIOptr = ptr [count];
       if(flag) gpRegs->BANK_REGISTERS [0].OUT_DATA &= ~0x01;
       else gpRegs->BANK_REGISTERS [0].OUT_DATA |= 0x01;
       flag = !flag;
    }

  • I'm afraid the cache confuses me somewhat.  I've added the following two calls, but they don't seem to have an affect. 

    CACHE_setL1DSize (0);

    CACHE_setL2Size (0);

    I'm assuming this is not the way to disable the global d-cache.  Can you point me in the right direction on how to do this?

    The code I posted is the actual code.  I want to only toggle the GPIO_0 on the last word written, not every other word.  I want to write the first 31 words out the EMIF16 with GPIO_0 set to 1, then turn GPIO_0 off, then write the 32nd word, then turn GPIO_0 on again.

  • Andrew,

    I'm sorry. I misunderstood your logic. I'm not sure on how to disable cache in your code as I'm not familiar with C6678 code base. You can check the C6678 DSP document to understand how enable/disable cache.

  • Andrew, I am not sure if this will help, but if it is safe to do so, you should try doing a dummy read from the EMIF memory space before you toggle your GPIO. I'm pretty sure that the Read will not be re-ordered before the the writes are complete, so the core will stall until the read can complete, and you should be assured that all of the write transactions have completed before your schange the state of the GPIO pin. Certainly it is worth a try... Best regards, B.J. Buchalter