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.

OMAP-L138 UPP sporadic misbehaviour

We have a problem with our uPP implementation that occurs in rare cases (probablity 0.5%).
The uPP interface is operated in duplex mode 0 (RX: channel A; TX: channel B),
16 bit wide data at 75 MHz.

  UPPCR = 0x8E
  UPDLB = 0x0
  UPCTL = 0x02020006
  UPICR = 0x00380038
  UPIVR = 0x0
  UPTCR = 0x0 (64 byte thresholds)

In TX direction, data is sent out on a periodical basis, triggered by a timer.
In this direction, the problem is observed in a special scenario, where data
is transferred from external SDRAM, intermixed with data from internal RAM.

It looks as if the data from the external SDRAM is sometimes sent twice
instead of once, although the channel descriptors appear to be correctly set.

In the error scenario, we have read the channel's status registers just before
and after triggering the DMA transfer. In the following I try to describe what
we have observed.

Transfer 1 (data from internal RAM (516 bytes)):
  before triggering the transfer: UPQS0 = 0x11F00900, UPQS1 = 0x00020000, UPQS2 = 0x80
  triggered by writing:           UPQD0 = 0x11F006C0, UPQD1 = 0x00010204, UPQD2 = 0x0
  just after the trigger:         UPQS0 = 0x11F00780, UPQS1 = 0x000100E8, UPQS2 = 0x41
 
Transfer 2 (data from external SDRAM (68 bytes)):
  before triggering the transfer: UPQS0 = 0x11F006C0, UPQS1 = 0x00020000, UPQS2 = 0x21
  triggered by writing:           UPQD0 = 0xC004C4C0, UPQD1 = 0x00010044, UPQD2 = 0x0
  just after the trigger:         UPQS0 = 0xC004C500, UPQS1 = 0x00010040, UPQS2 = 0x71
 
Transfer 3 (data from internal RAM (260 bytes)):
  before triggering the transfer: UPQS0 = 0xC004C4C0, UPQS1 = 0x00020000, UPQS2 = 0x70
  triggered by writing:           UPQD0 = 0x11F00900, UPQD1 = 0x00010104, UPQD2 = 0x0
  just after the trigger:         UPQS0 = 0x11F009C0, UPQS1 = 0x000100C0, UPQS2 = 0x41

We have also read the contents of registers UPPCR and UPPISR.
UPPCR appears always to be 0x8E and UPISR = 0x1A10.

The data sent out in transfers 1 and 2 is perfect. The data sent out in transfer 3
and all the following transfer is corrupt. It looks as if the 68 bytes of the transfer 2
are sent out again at the beginning of transfer 3, followed by the first 192 bytes
of the 260 bytes requested in the 3rd transfer.


Question 1: Do you have an explanation for the observed malfunction?

Question 2: Is it maybe not allowed to mix DMA transfers from different sources -
internal RAM and SDRAM?

Question 3: Is it possible to derive any information from this watermark indication in reg. UPQS2?
In the documentation, it is said that this field records the FIFO block emptiness
when the channel is operated in transmit mode. Reading this field often shows values of 0x2, 0x4
or 0x8 when the uPP interface is in a good condition. When the transmission has failed, a
value of 0x7 can be read.

Best regards

Jörg

  • Joerg,

    I'm not sure what's causing this issue.  It is definitely supported to mix/alternate memory regions for successive uPP transfers.  Does this issue always occur when the above sequence is run, or only 0.5% of the time?  I want to get a better idea how reliably you can reproduce this issue.

    Also, when programming the UPQDx or UPIDx registers, I generally observe the following:

    1. One write per register, per transfer (i.e. don't write individual register fields separately)
    2. Declare all register pointers with volatile keyword

    You're probably already observing these guidelines, but I like to dispense with the easy answers first.

  • Joe,

    the following code snippets shall show what we have implemented.
      The register pointers are defined as "volatile".
      The 3 registers are written as "one write per register".
      The global interrupt is disabled to write the 3 registers
      in an atomic way.

    typedef volatile unsigned int OMAPreg_t;
    #define UPP_ADDR  ( ( OMAPreg_t * )0x01E16000 )
    #define UPP_UPQD0       ( 0x60 / 4 )
    #define UPP_UPQD1       ( 0x64 / 4 )
    #define UPP_UPQD2       ( 0x68 / 4 )

    restore_csr = _disable_interrupts();
    UPP_ADDR[ UPP_UPQD0 ] = (unsigned int)xmit_buf;
    UPP_ADDR[ UPP_UPQD1 ] = UPP_UPQD1_LNCNT | (byteSize & UPP_UPQD1_BCNTH_MASK);
    UPP_ADDR[ UPP_UPQD2 ] = 0;
    _restore_interrupts( restore_csr );


    Our basic experience is that the transfer via the UPP bus normally works rather reliably.
    We have implemented stress tests, in which a lot of data of different size, is transferred
    from/to OMAP-internal memory and this works rather perfect.

    In the special scenario that I have described, data is transferred from external SDRAM
    mixed with data from internal RAM and for this we have observed the missbehaviour.

    We have written scripts to trigger the transfer of data with a selectable size in a controlled way.
    The script triggers e.g. 1000 transfers. With this we have made the following observation:
    For data sizes smaller than or equal 64 bytes, the transfer works fine with 100%.
    For data sizes bigger than 64, e.g. 68, 72 or 76, the misbehaviour can often be observed.
    On average, up to 200 transfers are executed in a perfect way before the first transfer failure occurs.
    This is the reason why I have said that it occurs with a probability of 0.5%.

    In the mean time, we have changed our SW in such a way, that this scenario is avoided.
    Before we trigger the uPP transfer, we copy all the data from external RAM to the internal one.
    This solution works with 100%. Since this does not occur that often in our SW, the additional
    copy of data is acceptable for the time being. Nevertheless, it would be interesting what
    could cause the effect.

    Regarding the watermark values, we have observed that it varies in the range betw. 0x0 - 0x8.
    Values 0x9 up to 0xF do not occur apparently. The value 0x7 is also a good value. I suppose
    that these values represent a normal behaviour of the uPP bus.

    Best regards

    Jörg

     

  • Joerg,

    Your procedure for programming the DMA descriptor registers seems correct.  Thank you for providing additional information about the issue and how/when it occurs.  We will have to see if we can reproduce the issue locally.  In the meantime, I'm glad to hear that you have found a workaround for your system.