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.

SM470R1B1M-HT Issue: SPI RX using DMA

Other Parts Discussed in Thread: SM470R1B1M-HT

I'm using the IAR SM470R1B1M-HT Kickstart kit and Embedded Workbench to test my MCU firmware, and have been debugging this problem for 3 days.

I'm trying to receive ten 16-bit data via SPI (SPI1BUF) and put them in an array (SPI_DATA). Prior to DMA operation, I would call the DMA_init function (refer below) and pass the address of SPI_DATA[0] and number of transfers (10) to the function. Data is sent from a DSP and I've used an oscilloscope to verify that data is indeed being transmitted.

Everything works well if there is no error in transfers (10 data sets received sequentially every time). I simulated an error condition whereby only 9 data sets were received, and the DMA responded correctly by filling only SPI_DATA[0] - SPI_DATA[8]. I tried to reset the DMA by calling DMA_init. Subsequent data set received will occupy SPI_DATA[9] and immediately indicate that DMA operation is complete, instead of starting from SPI_DATA[0] and continuing to receive 10 data sets.

In other words, it appears that the DMA controller does not update the destination address and count, even if I set the STOP bit on the DMA at the start of initialization. I've tried loading the code in RAM and on-board FLASH, re-loading the code and re-starting the IAR Embedded Workbench Software, to no avail. The only reset method that works is to power cycle the evaluation board.

I would appreciate anyone's advice on what I'm doing wrong here. Also attached are screenshots showing the sequence of events I described above.

*******************************************************************************************************

void DMA_init(unsigned long* spi_rx_data, unsigned cnt){
DMAGD = 0x2;
DMACPSC = 0;
DMACCP0 = 0;
DMAS = 0;
// 32-bit R/W, Destination increment 1, Source constant
// Dest. module ctrl by fine mem select 2, Src module ctrl by peripheral, no data chaining
DMAC00 = 0 | (2<<13) | (1<<11) | (2<<5) | (15<<1);
// ENABLE INTERRUPT ONLY FOR TROUBLESHOOTING!!////////////
DMAC00 |= (1<<15);
//////////////////////////////////////////////////////////
DMASA00 = (unsigned long)&SPI1BUF; // Source Address:
DMADA00 = (unsigned long)spi_rx_data; // Destination Address
DMATC00 = cnt; // Transfer count
// DMA Channel 1 Setup (SPI1 end-receive)
DMACC0 = 0 | (1<<6)| (1<<5); // (DMA Ch1 Interrupt on Line 0, no op during suspend, DMA on request
DMAGC = 0; // No halt, normal priority, BMSS = 0, channel service size = 1; for service size of 10: | (0x9)
DMAGD = 0; // Clear STOP and HALT mode
DMACPS |= (1<<0); // Enable Control Packet 0
DMACCP0 = 0 | (1<<14); // Enable Channel 1, point to it Control Packet 0
}
************************************************************************************************************

  • Roy, sorry for the delay.

    I did get some feedback to help isolate your issues.

    1)      User is not hitting the Arbitration boundary. (FIFO could not be flushed).  Doing a Module Software reset will clear all.. Note: It will clear all other DMA channels too.

    2)      User can check whether channel pending register is cleared before next set of transfer.

    3)      If there is option to Bypass FIFO he can enable that but through put of such configuration will be less.

    --

    Regards,

    Wade

  • Hi Wade,

    Appreciate the reply. Unlike the OMAP-L137-HT (which is what the SM470R1B1M-HT is interfacing to), the MCU's DMA does not operate with a FIFO, to my knowledge. I've also gone through the TMS470R1x DMA and SPI Reference Guides (SPNU194 Nov '02 and SPNU195E Aug '05 respectively) and could not locate a DMA reset register. If you could point me to the correct document and section for (1) & (3), I would greatly appreciate it.

    For (2), if you are referring to the Pending interrupt in the DMA Status register (Bit 16), yes it gets cleared prior to the next set of transfer under non-error conditions.

  • Roy, sorry the advice was generic DMA based and apparently not directly tied to the R1B1M.

    I have looked at this further, and have a couple question.

    The Silicon errata indicates that STOP should not be used.  From your description, you indicate you halt.  However, inspection of the code shows that DMAGD is set to 0x2 at the beginning of the init routine.  This is setting the stop bit.  I think I am following the code correctly.  Forgive me, as I am not coding expert.

    Can you test this with only using the halt to reset the DMA?

    Regards,

    Wade

  • Good morning Wade,

    You are correct. I saw the errata after making the first post, and have tried with HALT (0x1) in place of STOP (0x2). Issue remains.

    For both HALT and STOP, I quote page 25 of the DMA User Guide (SPNU194):

    "When this bit is set to one, the DMA controller finishes the current transaction and updates the configuration (DMAC), source address (DMASA), destination (DMADA), and the transfer count (DMATC) registers of the control packet...."

    Let's say the initial DMA setup is to transfer 10 datasets. If HALT/STOP is called after 8 datasets are transferred, the DMA Control Packet Registers (DMAC, DMASA, DMADA, DMATC) should be updated. In my case, I configured DMAC00, DMASA00, DMADA00 and DMATC00 for DMA transfers from SPI RX Buffer to RAM. At the end of 8 transfers, if I call HALT/STOP, I should expect to see DMASA00 remain the same (as I'm getting data from SPIBUF everytime), DMADA00 updated to 8 addresses away (RAM) and DMATC00 updated to 2 (since 8 of 10 transfers has occurred).

    I don't see the updates happening. Is this normal? The only time I've seen updates is when 10 datasets have been transferred.

    Best regards,

    Roy