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
}
************************************************************************************************************
