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.

SPI uDMA Rx interrupts going crazy

I am programming on a TM4C1294. I have a fairly complicated project that has been working well for a number of months until a recently discovered bug described below.

I use SPI2 and uDMA to receive data from a secondary processor (Tiva as slave). The SPI receives 32 bit data at 40KHz, but uses the uDMA to ping-pong transfer this data into a buffer and interrupt the processor at 1kHz. Since the SPI accepts up to 16 bit words, the uDMA is set to transfer 80 words before it interrupts the uP.

I use the USB to receive commands from the PC. Everything was working until I introduced a longer command (~300 bytes). When I send this command usually the processor locks up. If I reduce the length of the command a little bit the lock up becomes less frequent. Also, if I disable SSI interrupts, the command seems to always be received correctly at its full length.

In the SPI interrupt routine, I placed a GPIO toggle and noticed that I enter the ISR at the expected 1khz normally, but after I send my long USB command, I begin to enter the ISR much faster (like 184 khz). I have attached my SPI init and ISR code for reference.

Possible work-around seems to be making my command smaller or disabling data receipt from the secondary processor, both of which are feasible. I just don't want to mask another bigger problem.

//*****************************************************************************
//
// The control table used by the uDMA controller.  This table must be aligned
// to a 1024 byte boundary.
//
//*****************************************************************************
#if defined(ewarm)
#pragma data_alignment=1024
uint8_t pui8ControlTable[1024];
#elif defined(ccs)
#pragma DATA_ALIGN(pui8ControlTable, 1024)
uint8_t pui8ControlTable[1024];
#else
uint8_t pui8ControlTable[1024] __attribute__ ((aligned(1024)));
#endif

static uint16 PeakDataBufferA[DATA_BUFFER_SIZE];  //Transfer data here to give pointer to data processor to handle
static uint16 PeakDataBufferB[DATA_BUFFER_SIZE];


static uint16 blockSize = 0;

//*****************************************************************************
//
// The interrupt handler for uDMA errors.  This interrupt will occur if the
// uDMA encounters a bus error while trying to perform a transfer.  This
// handler just increments a counter if an error occurs.
//
//*****************************************************************************
static uint32_t g_ui32uDMAErrCount = 0;
static Void uDMAErrorHandler(UArg arg)
{
  uint32_t ui32Status;

  //
  // Check for uDMA error bit
  //
  ui32Status = MAP_uDMAErrorStatusGet();

  //
  // If there is a uDMA error, then clear the error and increment
  // the error counter.
  //
  if(ui32Status)
  {
      MAP_uDMAErrorStatusClear();
      g_ui32uDMAErrCount++;
  }
}

//*****************************************************************************
//
// The interrupt handler for uDMA interrupts from the SPI channel.
// DISPATCHED FROM THE SPI MODULE.
// This interrupt will notify the data Processor.
//
//*****************************************************************************
static Void uDMAIntHandler(UArg arg)
{
  uint32_t ui32Status;
  uint32_t ui32Mode;

  MAP_GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, ~0);

  //
  // Read the interrupt status of the SSI.
  //
  ui32Status = MAP_SSIIntStatus(SSI2_BASE, 1);

  //
  // Clear any pending status, even though there should be none since no SSI
  // interrupts were enabled.  If SSI error interrupts were enabled, then
  // those interrupts could occur here and should be handled.  Since uDMA is
  // used for both the RX and TX, then neither of those interrupts should be
  // enabled.
  //
  MAP_SSIIntClear(SSI2_BASE, ui32Status);

  MAP_GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_4, 0);

  //
  // Check the DMA control table to see if the ping-pong "A" transfer is
  // complete.  The "A" transfer uses receive buffer "A", and the primary
  // control structure.
  //
  ui32Mode = MAP_uDMAChannelModeGet(UDMA_CHANNEL_SSI2RX | UDMA_PRI_SELECT);

  //
  // If the primary control structure indicates stop, that means the "A"
  // receive buffer is done.  The uDMA controller should still be receiving
  // data into the "B" buffer.
  //
  if(ui32Mode == UDMA_MODE_STOP)
  {
    if(controlWord & CONTROL_WORD_DataMode)
    {
      DataProcessorTask_NotifyVideoDataReady(&PeakDataBufferA[0], blockSize);
    }
    else
    {
      DataProcessorTask_NotifyDataReady(&PeakDataBufferA[0], blockSize);
    }

    //
    // Set up the next transfer for the "A" buffer, using the primary
    // control structure.  When the ongoing receive into the "B" buffer is
    // done, the uDMA controller will switch back to this one.
    MAP_uDMAChannelTransferSet(UDMA_CHANNEL_SSI2RX | UDMA_PRI_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)(DATA_SSI_BASE + SSI_O_DR),
                               &PeakDataBufferA[0], blockSize);
  }

  //
  // Check the DMA control table to see if the ping-pong "B" transfer is
  // complete.  The "B" transfer uses receive buffer "B", and the alternate
  // control structure.
  //
  ui32Mode = MAP_uDMAChannelModeGet(UDMA_CHANNEL_SSI2RX | UDMA_ALT_SELECT);

  //
  // If the alternate control structure indicates stop, that means the "B"
  // receive buffer is done.  The uDMA controller should still be receiving
  // data into the "A" buffer.
  //
  if(ui32Mode == UDMA_MODE_STOP)
  {
    if(controlWord & CONTROL_WORD_DataMode)
    {
      DataProcessorTask_NotifyVideoDataReady(&PeakDataBufferB[0], blockSize);
    }
    else
    {
      DataProcessorTask_NotifyDataReady(&PeakDataBufferB[0], blockSize);
    }

    //
    // Set up the next transfer for the "B" buffer, using the alternate
    // control structure.  When the ongoing receive into the "A" buffer is
    // done, the uDMA controller will switch back to this one.
    MAP_uDMAChannelTransferSet(UDMA_CHANNEL_SSI2RX | UDMA_ALT_SELECT,
                               UDMA_MODE_PINGPONG,
                               (void *)(DATA_SSI_BASE + SSI_O_DR),
                               &PeakDataBufferB[0], blockSize);
  }
}

//--------------------------------------------------------------------
// FPGA Enable Displacement Data transmission
//--------------------------------------------------------------------
void FPGA_DataChannel_Initialize(void)
{
  MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

  //--------------------------------------
  // Set up SSI port for FGPA data channel
  //--------------------------------------
  MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);

  // Configure and enable the SSI port for SPI slave mode.  Use SSI2,
  // system clock supply, idle clock level low and active low clock in
  // freescale SPI mode, slave mode, 10MHz SSI frequency, and 16-bit data.
  // For SPI mode, you can set the polarity of the SSI clock when the SSI
  // unit is idle.  You can also configure what clock edge you want to
  // capture data on.  Please reference the datasheet for more information on
  // the different SPI modes.
  MAP_SSIConfigSetExpClk(DATA_SSI_BASE, PRM_GetSystemClockFrequency(), SSI_FRF_MOTO_MODE_0,
                         SSI_MODE_SLAVE, 10000000, 16);

  // Enable the uDMA controller error interrupt.  This interrupt will occur
  // if there is a bus error during a transfer.
  MAP_IntEnable(INT_UDMAERR);

  // Enable the uDMA controller.
  MAP_uDMAEnable();

  // Point at the control table to use for channel control structures.
  MAP_uDMAControlBaseSet(pui8ControlTable);

  MAP_uDMAChannelAssign(UDMA_CH12_SSI2RX);


  // Enable the SSI module
  MAP_SSIEnable(DATA_SSI_BASE);
  MAP_SSIDMAEnable(DATA_SSI_BASE, SSI_DMA_RX);


  // Put the attributes in a known state for the uDMA software channel.
  // These should already be disabled by default.
  MAP_uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI2RX,
                                  UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |
                                 (UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK));

  // Configure the control parameters for the SSI channel.  The channel
  // will be used to transfer between the SPI RX FIFO and memory buffers,
  // 16 bits at a time. Therefore the data size is 16 bits, and the address
  // increment is 16 bits for the destination. The arbitration size will be
  // set to 4, which causes the uDMA controller to rearbitrate after 4 items
  // are transferred.  This keeps this channel from hogging the uDMA controller
  // once the transfer is started, and allows other channels cycles if they
  // are higher priority.
  //
  MAP_uDMAChannelControlSet(UDMA_CHANNEL_SSI2RX | UDMA_PRI_SELECT,
                            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 |
                            UDMA_ARB_4);

  MAP_uDMAChannelControlSet(UDMA_CHANNEL_SSI2RX | UDMA_ALT_SELECT,
                            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 |
                            UDMA_ARB_4);


  //Set-up uDMA interrupts:
  Hwi_Handle  hwi;

  hwi = Hwi_create(INT_UDMAERR, uDMAErrorHandler, NULL, NULL);
  if (!hwi)
  {
    System_abort("Couldn't create uDMA error hwi");
  }

  hwi = Hwi_create(INT_SSI2, uDMAIntHandler, NULL, NULL);
  if (!hwi)
  {
    System_abort("Couldn't create uDMA hwi");
  }

  //Set-up interrupt for pin used to frame video data:
  MAP_GPIOIntTypeSet(GPIO_PORTP_BASE, GPIO_PIN_5, GPIO_DISCRETE_INT | GPIO_FALLING_EDGE);
  hwi = Hwi_create(INT_GPIOP5, gpioP5_IntHandler, NULL, NULL);
  if(!hwi)
  {
    System_abort("Couldn't create gpio P5 hwi");
  }

  //Set-up interrupt for pin used to frame peak data:
  MAP_GPIOIntTypeSet(GPIO_PORTP_BASE, GPIO_PIN_0, GPIO_DISCRETE_INT | GPIO_FALLING_EDGE);
  hwi = Hwi_create(INT_GPIOP0, gpioP0_IntHandler, NULL, NULL);
  if(!hwi)
  {
    System_abort("Couldn't create gpio P0 hwi");
  }


}

  • Hello Issac,

    There is nothing obviously wrong in the setup of the SPI. When you send the larger command via USB and the Processor Locks Up, what exactly the lock up do (where does it loop or fault). Did you try increasing the size of heap?

    One of the reasons that I can think of the ISR firing quickly is that the DMADONE is getting fired all the time. This could potentially mean that the RXDMA request is firing faster which in turn means that the RXFIFO has a data which is not being read.

    Regards
    Amit
  • Amit, thank you for your response.

    It looks like to processor isn't locked, but maybe it is continually servicing the ISR. All other tasks stop running.

    After the "lock up", I placed a breakpoint in the ISR and see that it continually enter the ISR with the DMARXMIS bit set, but UDMA_MODE_STOP never occurs (so most of the ISR code isn't run).

    I did not try increasing the heap.

  • Hello Issac,

    Not sure but which interrupts are being enabled in the SSI Interrupt Mask register?

    Regards
    Amit
  • Only SSI_IM_DMARXIM
  • Hello Issac

    I checked the attached code and there was the define UDMA_CHANNEL_SSI2RX I could not find in TivaWare.

    Secondly can you check the actual memory address for the UDMA vector table that would show the control words & the SSIM Register snapshot, send them across when the interrupts keep on firing.

    Regards
    Amit
  • I defined UDMA_CHANNEL_SSI2RX as 12 (based on uDMA Channel Assignments Table 9.1).

    SSI_IM = 0x00000010
    SSI_RIS=0x0000005F
    SSI_MIS=0x00000010

    Snapshot of the controlTable at address 0x20009000 (is this what you wanted?)

    pui8ControlTable
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    4000A008 200074BB 5D0084B3 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    4000A008 20007CBB 5D0084B3 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
  • That didn't format very well - I attached the controlTable in txt document

    pui8ControlTable
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    4000A008	200074BB	5D0084B3	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    4000A008	20007CBB	5D0084B3	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000
    00000000	00000000	00000000	00000000	00000000	00000000	00000000	00000000

  • Hello Issac,

    Can you make a few changes to the code like moving the following code after the uDMA has been enabled.

    // Enable the SSI module
    MAP_SSIEnable(DATA_SSI_BASE);
    MAP_SSIDMAEnable(DATA_SSI_BASE, SSI_DMA_RX);

    Also when you restart the code, ensure that the SSI and uDMA peripherals are reset using SysCtlPeripheralReset function,

    Regards
    Amit
  • Hi Amit,

    I moved the SSI enables until the end of the DataChannel_Initialize function. Is this what you meant? They were already located after MAP_uDMAEnable().

    I also added the PeripheralResets.

    These didn't make any difference.

    I sent you a private message with the full SPI/uDMA code to give you a more complete picture.

    Thank you,
    Isaac
  • This problem is probably caused by the SSI module and the USB module both needing access to SRAM. If the USB receiver has control of the SRAM, then the SSI receiver can't put data into its FIFO and a data overrun occurs. The data overrun triggered the SSI interrupt routine even though I hadn't enabled the receive overrun interrupt (and therefore was not checking it in the interrupt routine).

    The problem goes away by decreasing the length of commands sent via USB or by slowing down the baud rate of the SSI bus. In the future I will probably do both (I was running the SSI at 10 Mhz which is the upper limit and faster than necessary).

    It turns out that this condition is detectable because the Receive Overrun Interrupt bit is set in SSI Raw Interrupt Status register. Even though I have stopped observing this error condition by slowing the baud rate of the SSI, I wanted to add code that would gracefully recover if it did occur unexpectedly.

    I added code to check the ROR bit when the DMA interrupt occurs. If the overrun is indicated, I set a flag flag that says something went wrong and then shut down the DMA and SSI interrupts. Meanwhile, there is a task performing various slow-speed system maintenance operations that now will check this error flag and restart the SSI communication if the error has occurred.

    Thank you, Amit, for helping me debug through this.

    Isaac

  • Hello Issac,

    No problem. Actually it is contention between CPU and uDMA, I would still try as a last attempt enable the burst feature or move the uDMA Buffer to different bank of the SRAM to get the bandwidth.

    Regards
    Amit
  • Hi Amit,
    I'm just now trying out your two suggestions. So far I haven't seen any improvement with the burst feature.
    When you say to move the uDMA buffer are you referring to the two destination buffers - where the uDMA is placing data?

    Thanks,
    Isaac
  • Hello Issac,

    Yes, that would be the destination buffer.

    Regards
    Amit
  • I moved the destination buffers and the uDMA control table to a completely different location in SRAM and it also did not help.
  • Hello Issac,

    It seems we have reached the max capability of the device to handle such traffic.

    Regards
    Amit
  • Amit Ashara said:
    Hello Issac,

    It seems we have reached the max capability of the device to handle such traffic.

    Regards
    Amit






    Hello Amit.

    I think this is another issue. Because I am seeing the same behaviour with the SSI0 port when using it as a slave with external clocks, and I am not using USB or any other dma peripheral.

    The funny thing is if we set SSI master as a master works, if we use it as Slave we see the same:
    SSI0_IM = 0x00000010
    SSI0_RIS=0x0000005F
    SSI0_MIS=0x00000010

    Amit, could you provide a purely slave/uDMA example to check?

    Regards.

  • Hello PAk,

    I don't have a SSI with UDMA case yet. However did you reset the peripheral before using the same in Slave mode? Also is the clocking requirement for slave being met by the external clock w.r.t System clock?

    Regards
    Amit
  • Amit Ashara said:
    Hello PAk,

    I don't have a SSI with UDMA case yet. However did you reset the peripheral before using the same in Slave mode? Also is the clocking requirement for slave being met by the external clock w.r.t System clock?

    Regards
    Amit

    Yes, I did.

    SSIDisable(SSI0_BASE);
    
    SSIConfigSetExpClk(SSI0_BASE, g_ui32SysClock, SSI_FRF_MOTO_MODE_0, SSI_MODE_SLAVE_OD, 200000, 16);//using 200kHz clk signal
    
    uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, (void*) (SSI0_BASE + SSI_O_DR),signal_buffer, n_samples);// Setup RX channel primary transfer parameters.
    
    SSIEnable(SSI0_BASE);

    However, I understand that as a slave, the databit rate is set by master.

    I think it is worth that you "get" that example to check. The behaviour of registers is strange.

  • Hello PAk,

    Yes. The data rate is decided by the master. However the design is synchronous and for converting the serial bit stream to a parallel data register load, the input signals need to be sampled. For this specific condition the Master clock SSInCLK may not be more than 1/12 of the system clock.

    Regards
    Amit
  • PAk said:

    However, I understand that as a slave, the databit rate is set by master.  

    Out beyond my skis here - yet "logic" compels my comment:   "While the data rate is set by the "master" - that (master set) data rate must "still" comply w/the "Slave's" data rate specification!    Writing quoted does not make that "rate compliance" (by master to slave's need) at all clear.

  • Amit Ashara said:

    Yes. The data rate is decided by the master. However the design is synchronous and for converting the serial bit stream to a parallel data register load, the input signals need to be sampled. For this specific condition the Master clock SSInCLK may not be more than 1/12 of the system clock.

    So you are saying the maximum bitrate as slave is (120MHz/12=) 10Mbps?

    I am not so sure, since I have another example where in the same Tiva board, one port is master (SSI0) and another is slave(SSI2) using 12.5Mbps and it is working fine.

    In this case, as you can see, the bitrate set matches the external clock.

  • PAk said:
    slave(SSI2) using 12.5Mbps and it is working fine.

    Always unwise to, "violate vendor's specs!"    (such often causes near immediate "DQ" (disqualification) when seeking funding)

    Understand that vendor draws such spec over (usually - but not always) temperature, voltage range, voltage settings, clock settings & "downstream" process changes.

    Was your testing able to "capture" over that (wide range) of inputs - and/or was your test methodology adequate in its design, length & sophistication?     (when I past worked @ similar, semi-giant - we employed "serious" B.E.R. test device to note the "onset of errors" as we "challenged" the device...)

    You're close to "meeting spec" - Risk-Reward seems very much against any (deliberate) spec violation!      From experience, VCs/similar others very much prefer that designers choose a device which "meets their identified goals/objectives" and "NOT" attempt to "bend a "non-complying" device" to those same, goals/objectives!    

  • Hello PAk,

    The timing for the worst case is 1/12. So you may have one silicon device that may clock as 12.5Mbps but not every. Just off the record, I have attained on a single piece 20Mbps, but the same case did not work on all test devices. Characterization of devices before production is what the electrical section binds the design at.

    In a similar fashion a few devices did work at 140MHz, but then we do not qualify above 120MHz.


    WARNING: Irrespective of the statement, Exceeding device specification is not guaranteed by TI.

    Regards
    Amit

  • May I note that the "beyond spec" results you report may not have enjoyed that same advantage over "ALL" certified temperature, voltage & clock settings!    And - as you note - such is not likely to be "guaranteed" across a wide distribution of "typical" devices.    (crap-shoot, anyone?)
     
    To be certain - designers/users should, "Take no pride" in "beating the spec!"    Full compliance with the spec insures the most robust design - and provides (some) legal defense - which is (lost) when pride (often false btw, based upon individual device variance) rises above compliance...

  • Hello cb1,

    Indeed. That is why the use "off the record", and the fact that not every test device achieves the same. Characterization indeed limits the operation range over PVT

    Regards
    Amit
  • Hi Amit,

    My thought, "Off the record" may not be (really) seen/heard as forcefully as, "Do NOT do this!"   "Throwing away" the protections the manufacturers provide when operating w/in spec - and insuring VC "rejection" - is a very high price to pay for so slight - and transient - a gain!

  • Hello cb1

    Sure. i will edit my post with the WARNING

    Regards
    Amit
  • cb1_mobile said:
    Always unwise to, "violate vendor's specs!"    (such often causes near immediate "DQ" (disqualification) when seeking funding)

    But in the example we are testing, and doesn't work, we are using a SSICLK of 200kHz  in the SSI0 port, far away of the limit of 10MHz of the slave (and 60MHz for the master).

    So it is another thing, I still think that an example of a SSI slave using uDMA is required.

  • Both Amit & I read your wording as, "Clear challenge" to T.I.'s spec - (and noted a degree of pride in so doing.)

    Being (perhaps) bit more experienced - an alarm was sounded - in your and other's behalf - alerting to the (mostly negative) consequences if/when so doing. (i.e. violating vendor's published spec)
  • cb1- said:
    Both Amit & I read your wording as, "Clear challenge" to T.I.'s spec - (and noted a degree of pride in so doing.)

    Actually, I didn't know the specs (I started with a master port (SSI0), then added a slave (SSI3) at the same rate [assuming the same rates for both master and slave] and it worked). I think it is working because it is generated with the same internal timer as the master port.

    What bothers me, is that it is not working as a slave in SSI0 at only 200kHz (or 1MHz, or anything in the specified range).

  • PAk said:

    So you are saying the maximum bitrate as slave is (120MHz/12=) 10Mbps?

    I am not so sure, since I have another example where in the same Tiva board, one port is master (SSI0) and another is slave(SSI2) using 12.5Mbps and it is working fine. 

    Your quote (above) reveals your, "spec violation."     Note that both Amit & I have advised against such practice...

  • cb1- said:
    Note that both Amit & I have advised against such practice...

    Ok, Roger that.

    Now, what about the simple SSI0 as slave not working inside the specs?

  • Good that - goal is to "try" to steer you (away) from that which is "known" to cause trouble.

    To your "simple" SSI0 Slave - would not your creating the smallest, simplest program which demonstrates such, "ill behavior" go far toward its resolution? You cannot really expect Amit to load your entire program - as your code grows in size/complexity - troubleshooting time/effort grows exponentially.

    Your skill in "causing the issue" - under greatly reduced code size & conditions - best enables Amit's, yours and others ability to remedy...
  • cb1- said:
    To your "simple" SSI0 Slave - would not your creating the smallest, simplest program which demonstrates such, "ill behavior" go far toward its resolution? You cannot really expect Amit to load your entire program - as your code grows in size/complexity - troubleshooting time/effort grows exponentially.

    In the first post of this thread, the original poster attached a sample code, that it has not been tested by TI.

    After that, I reported the same issue in similar conditions, so it seems a silicon/design fail. 

    cb1- said:
    Your skill in "causing the issue" - under greatly reduced code size & conditions - best enables Amit's, yours and others ability to remedy...

    I agree with that but I have to debug my code/tools, on the other hand TI has to debug his.

    This is an issue neither solved nor even tested.

  • PAk said:

    This is an issue neither solved nor even tested.  

    Feel your pain (really, I do) yet did not vendor's Amit invest good time/effort - in "best he could" duplication of your key/critical MCU usage - and he did not detect your issue.

    While the earlier poster reported (somewhat) similar conditions to your own - there's often a "world of difference" hidden by the camouflaging, "somewhat!"

    Again - anything you can do to reduce the size, scope, and complexity of your MCU usage - and/or anything which raises the frequency of the issue - or causes its appearance, "sooner rather than later" - proves very much to your (and your helpers') advantage.  

  • Hello PAk,

    I do not have every setup that a forum user has. This greatly limits my ability to be able to debug and leads to a lot of post to and fro which at times has to be closed on terms neither the poster nor me would like. Note that TM4C is a complicated uC and is not marketed as a specific uC unlike low power and motor control from TI's portfolio.

    Clarity is sought for every issue. Just like the ADC missing interrupt, this is a post which is highly dependent on exact conditions that are specific to a system. Would it not be rather unjust that TI (in this case me) is solving an issue without reproducing it. Solution to one issue at times has ripple effects that need to be understood. Otherwise a solution may just be the tip of an iceberg.

    So as cb1 suggested, if it can be boiled to a use case for me to debug with may be 2 LP's, I would be more than glad to help you out.

    Regards
    Amit
  • Well said, Amit - well said.     My small tech firm monitors & is active w/in multiple ARM & sensor forums - your effort & keenness here is (by far) unmatched! 

    PAk - hope it rings, "Loud/clear" that, "Two here, Feel your pain."      (both Amit & I root for your success - although likely for different reasons...)

    Yours is (apparently) a, "big-league" issue - and as such usually requires extreme focus, cunning, and effort to first isolate - then capture issue's trigger - & resolve.

    While you've provided far beyond "normal/customary" issue description - the complexity of the MCU & your intertwined, demanding peripheral usage - raises the degree of difficulty.     Few "magic bullets" exist for this one - you are the best "keeper" of your "beast" - and know best how to reduce its range & power - so that (others) have (some) chance to examine & assist...