Page 1 of 1

MOD54415 DSPI CS Assertion

Posted: Wed Apr 08, 2015 7:18 am
by mpgramlich
//Setup Code Below

Code: Select all

#define ADCSPI 1
#define dspiBaudRateADC 70000000
#define transferSizeBitsADC 24
#define CSPolarityIdleADC 0x0E //Chip select polarity at idle
							//DAC Idle High 0x0F
							//ADC Idle Low 0x0E

#define DACSPI 2
#define dspiBaudRateDAC 25000000
#define transferSizeBitsDAC 8
#define CSPolarityIdleDAC 0x0F//Chip select polarity at idle
							//DAC Idle High 0x0F
							//ADC Idle Low 0x0E

Code: Select all

    J2[25].function(1);//SPI1 clock ADC
    J2[27].function(1);//SPI1 Input ADC
   	J2[28].function(1);//SPI1 Out ADC
   	J2[30].function(1);//SPI1 chip select 0 ADC

   	J2[29].function(1);//SPI2 clock DAC
    J2[3].function(1);//SPI2 Input DAC
    J2[4].function(1);//SPI2 Out DAC
   	J2[38].function(1);//SPI2 chip select 0 DAC

    DSPIInit(ADCSPI,dspiBaudRateADC,transferSizeBitsADC,0x0E,
    			CSPolarityIdleADC,0,1,1,100,1);
    DSPIInit(DACSPI,dspiBaudRateDAC,transferSizeBitsDAC,0,
    			CSPolarityIdleDAC,0,1,1,0,0);
ADCTable, used to store raw ADC Data

Code: Select all

namespace ADCTable
{
	static const int size = 3000000;
	static volatile uint8_t __attribute__ ((aligned(2))) table[size*3] = { 0 }; //samples * 3 bytes each
	static double timeTable[size] = { 0 };
}
The ADC I am communicating with is an ADS8881. Chip Select tied to CONVST.
http://www.ti.com.cn/cn/lit/ds/sbas547c/sbas547c.pdf

Now on with my question/issue.

My issue is using the DMA engine to control a very long, continuous transfer- about 3 million bytes. Using the following DSPIStart call,

Code: Select all

DSPIStart(ADCSPI,NULL,ADCTable::table,ADCTable::size*3,&spiSemADC,true,DEASSERT_EVERY_TRANSFER)
I can see on my scope that the clock and chip select are asserted in the correct directions, but the chip select is not De-asserted every 24 bits like I have requested. It will only assert at the beginning, and de-assert at the end of the transfer.

The current solution is using strictly interrupts to drive the SPI peripheral

Code: Select all

for(i = 0; i < ADCTable::size; i++)
    {
    	DSPIStart(ADCSPI,NULL,&ADCTable::table[i*3],3,&spiSemADC,  false  ,1); 
    	OSSemPend(&spiSemADC, 0);
    }
This solution correctly asserts chip select every 24 bits and data that comes back is correct. However, this is not the solution I want because I need to be able to complete other tasks and communicate with other devices on other DSPI buses, specifically a DAC.

My question is, is there something I am doing obviously wrong, or is the DMA driver not capable of what I described?
If I need to, I can post scope pictures at a later point.

Thank you,
-Matt

Re: MOD54415 DSPI CS Assertion

Posted: Wed Apr 08, 2015 9:06 am
by mpgramlich
Looking through the DMA Driver, I cannot find where the command register for the SPI peripheral is concated on to the transmit buffer. I see the driver setups the proper ctars but not the command register.

Would I need to mask the command register on my transmit buffer for each spi frame?

Re: MOD54415 DSPI CS Assertion

Posted: Fri Apr 10, 2015 8:30 am
by mpgramlich
Update:

Updating to the latest Netburner Tools, 2.7.1 Beta, does not fix the issue. Any insight into this problem?

-Matt

Re: MOD54415 DSPI CS Assertion

Posted: Fri Apr 10, 2015 9:44 am
by dciliske
The driver is supposed to be able to do what you want it to do here. However, as the driver exists, it will never be able to do this with DMA (only in queued interrupt mode). The reason for this is that the way that the SPI command and tx data are entered. Basically, you have to buffer the tx data with the 16 bit command chunk and then write it to the DSPI PUSHR register. This required ganging two DMA channels together and raises the complexity of the general driver significantly.

The way that the DMA part of the driver even functions is that we abuse the chip select polarities. Before we start the transaction, we actually invert the polarity of whatever CS we want to assert and just don't bother actually asserting it. When we finish the transaction, if requested to deassert, we put the polarity back (or remember our state until such time as we are requested to deassert).

Given that you are trying to transfer a large amount of data and run in 24 bit mode deasserting every transfer there two options available to you:
  1. Pass the argument to DSPIStart that disables DMA.
  2. Rip the guts out of the DSPI driver and use it as a foundation for your application.
If you need/want the DMA support, you'll need to go with the second option. If you take that path, you'll need to use Revision 3 of the MCF5441x Reference Manual (Rev 4 doesn't have correct/complete information on the DMA engine). You'll end up using the cross channel chaining to fill two 32-bit staging buffers. The first will have the CommandMask for the lead 8/16-bits which will assert the CS and the second will deassert the CS. You will likely manually prime the staging buffers and then when the DSPI sends a DMA request, it will trigger a transfer out of the staging buffer and then perform a cross channel trigger to transfer from the main input buffer to replenish the staging buffer.

Now, all that said, just confirming, you are trying to get this working with DMA, and not just having the issue that the driver fails to deassert in 24 bit mode, correct?

-Dan

Re: MOD54415 DSPI CS Assertion

Posted: Sun Apr 12, 2015 3:21 pm
by mpgramlich
Now, all that said, just confirming, you are trying to get this working with DMA, and not just having the issue that the driver fails to deassert in 24 bit mode, correct?
Correct, I would like to get this working with DMA just because
of the amount of data moving.
The the interrupt control works, but only if I continuously call DSPI start in a loop advancing the point to my response structure. (see the last code snip in my first post)

The one thing I have not been able to find is where the command register is marked into the first 16 bits of the transfer. Could you point this out to me?

-Thank you
Matt

Re: MOD54415 DSPI CS Assertion

Posted: Mon Apr 13, 2015 1:42 pm
by dciliske
Well, that's the fifoCmd variable that gets or'ed onto in front of the data chunk. Specifically the CTAR selection for configuring between the 16-bit and 8-bit chunks to be transferred. Line 486 of dspi.cpp. That said, I went a head and fixed the bug that was preventing this from working and I'm sending you the copy in a PM.

-Dan

Re: MOD54415 DSPI CS Assertion

Posted: Tue Apr 14, 2015 6:08 am
by mpgramlich
dciliske wrote:Well, that's the fifoCmd variable that gets or'ed onto in front of the data chunk. Specifically the CTAR selection for configuring between the 16-bit and 8-bit chunks to be transferred. Line 486 of dspi.cpp. That said, I went a head and fixed the bug that was preventing this from working and I'm sending you the copy in a PM.

-Dan
Just expressing concern, the eventual plan is to transition to the NANO 54415 (should have mentioned that earlier). This fix is completely compatible with the NANO, right?

I will get back to you by the end of today will my testing on the MOD and Nano.

Thank you,
Matt

Re: MOD54415 DSPI CS Assertion

Posted: Tue Apr 14, 2015 7:30 am
by dciliske
Yes, this is compatible with the Nano. The Nano and Mod share the majority of their peripheral drivers.

Re: MOD54415 DSPI CS Assertion

Posted: Thu Apr 16, 2015 3:07 pm
by mpgramlich
Sorry for the late turn around, just getting back into my lab. Now that this is working, I have a few questions.

Looking at the code you provided, how can I adapt your fix to the other transfer sizes (8 bit, 16 bit, and 32 bit)?

I am also curious on why this addition was made to the canDoDMA function?

Code: Select all

if (DSPIModule::driverCxt[SPIModule].BitsPerQueue > 16) {
    return FALSE;
}
Removing this check still allows the driver to function properly and correctly assert the CS pin every 24 bits.

Thank you,
-Matt


*note the file comment on each picture

Re: MOD54415 DSPI CS Assertion

Posted: Thu Apr 16, 2015 5:45 pm
by dciliske
The reason that the > 16 check was added is that 17-31 bit transfers require utilizing CTARs 0 and 1. As explained before, when performing the DMA transfers, we are limited to only using CTAR 0. Therefore, we cannot use DMA for these higher bit sizes. 32 bit is a bit of a special case, where we really could support DMA, but that check just didn't pass at the time.

Are you asking how to adapt the outline I gave in the post or the correction I PMed?

-Dan