I have a custom board with a TMS320C6745 connected to a ADS7953 ADC. I would like to utilize the full capability of the ADC so I am using DMA.
The problem I am having is that the DMA controller isn't correctly incrementing its pointer in memory. Though it should be incremented by 2, it is only incremented by 1 and thus the data written to the SPI port overlaps.
I have looked at these related threads to no avail:
http://e2e.ti.com/support/dsp/omap_applications_processors/f/42/t/168604.aspx (Copied this code into Spi_edma, recompiled driver, recompiled test program, still broken)
http://e2e.ti.com/support/embedded/bios/f/355/t/89303.aspx (Tried this, still no)
http://e2e.ti.com/support/embedded/bios/f/355/t/170382.aspx (This too, no)
http://e2e.ti.com/support/embedded/bios/f/355/t/130781.aspx (This neither)
I'm out of ideas. Perhaps someone can attach a working copy of the source code and the compiled libraries. I'm not sure where the problem is at this point.
EDMA3 01.11.03.01
void SpiUserInit()
{
spiParams = Spi_PARAMS;
spiParams.hwiNumber = 8;
spiParams.spiHWCfgData.intrLevel = FALSE;
spiParams.opMode = Spi_OpMode_DMAINTERRUPT;
//spiParams.opMode = Spi_OpMode_INTERRUPT;
//spiParams.opMode = Spi_OpMode_POLLED;
spiParams.outputClkFreq = 15000000;
spiParams.loopbackEnabled = FALSE;
spiParams.edmaHandle = NULL;
spiParams.spiHWCfgData.configDatafmt[0].charLength = 16u;
spiParams.spiHWCfgData.configDatafmt[0].clkHigh = TRUE;
spiParams.spiHWCfgData.configDatafmt[0].lsbFirst = FALSE;
spiParams.spiHWCfgData.configDatafmt[0].oddParity = FALSE;
spiParams.spiHWCfgData.configDatafmt[0].parityEnable = FALSE;
spiParams.spiHWCfgData.configDatafmt[0].phaseIn = FALSE;
spiParams.spiHWCfgData.configDatafmt[0].waitEnable = FALSE;
spiParams.spiHWCfgData.configDatafmt[0].wDelay = 10;
spiParams.spiHWCfgData.intrLevel = TRUE;
spiParams.spiHWCfgData.waitDelay = TRUE;/**< True - enable format delay between 2 consecutive transfers ; */
spiParams.spiHWCfgData.pinOpModes = Spi_PinOpMode_SPISCS_4PIN;
spiParams.spiHWCfgData.delay.c2TDelay = 5; // < [IN] Chip-select-active-to-transmit-start-delay
spiParams.spiHWCfgData.delay.t2CDelay = 0; /**< [IN] Transmit-end-to-chip-select-inactive-delay */
//spiParams.spiHWCfgData.delay.t2EDelay = 0;/**< [IN] Transmit-data-finished-to-ENA-pin-inactive-time-out */
//spiParams.spiHWCfgData.delay.c2EDelay = 0;/**< [IN] Chip-select-active-to-ENA-signal-active-time-out */
Spi_init();
}
/* Buffer alignment is required when working in DMA Mode */
#pragma DATA_ALIGN(loopWrite, 128);
Uint8 loopWrite[ADC_BUF_SIZE];
/* Buffer alignment is required when working in DMA Mode */
#pragma DATA_ALIGN(loopRead, 128);
Uint8 loopRead[ADC_BUF_SIZE];
void init_adc()
{
GIO_Attrs gioAttrs = GIO_ATTRS;
Spi_ChanParams chanParams;
//if the edma support is required then we need to configure edma
EDMA3_DRV_Result edmaResult = 0;
if (NULL == hEdma)
{
edmaResult = edma3init();
if (EDMA3_DRV_SOK != edmaResult)
{
//Error in configuring the edma driver
LOG_printf(&trace,"\r\nEDMA3 : edma3init() failed\r\n");
}
else
{
LOG_printf(&trace,"\r\nEDMA3 : edma3init() passed\r\n");
}
}
chanParams.hEdma = hEdma;
//create SPI channel for transmission
spiHandle = GIO_create("/Spi1",IOM_INOUT,NULL,&chanParams,&gioAttrs);
if (spiHandle == NULL)
{
LOG_printf(&trace,"\r\n SPI Driver Handle creation Failed ");
}
}
void adc_read(int channel, Uint16 *buf, int count)
{
Spi_DataParam dataparam;
size_t size = 0;
/* clear the input and output buffers */
memset(loopWrite, 0x00, sizeof(loopWrite));
memset(loopRead , 0x00, sizeof(loopRead));
/* clear the spi params data structure */
memset(&dataparam,0x00, sizeof(Spi_DataParam));
//MANUAL MODE COMMAND for NEXT channel
int cmd = MODE_MANUAL | (channel << 7);
//Set data to be written
int i;
for(i = 0; i < count*2; i++)
{
loopWrite[i++] = (Uint8)cmd;
loopWrite[i] = (Uint8)(cmd >> 8);
}
dataparam.bufLen = 2*count;
dataparam.inBuffer = &loopRead[0];
dataparam.outBuffer = &loopWrite[0];
//CS needs to be toggled after every 16-bit word. The input is sampled at the CS signal's falling edge.
//dataparam.flags = Spi_CSHOLD;
dataparam.dataFormat = Spi_DataFormat_0;
dataparam.chipSelect = 0x01;
size = dataparam.bufLen;
// write command
GIO_write(spiHandle, &dataparam, &size);
//... do something with the data
}