MOD54415 DSPI CS Assertion

Discussion to talk about software related topics only.
Post Reply
mpgramlich
Posts: 6
Joined: Mon Apr 06, 2015 8:36 am

MOD54415 DSPI CS Assertion

Post 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
mpgramlich
Posts: 6
Joined: Mon Apr 06, 2015 8:36 am

Re: MOD54415 DSPI CS Assertion

Post 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?
mpgramlich
Posts: 6
Joined: Mon Apr 06, 2015 8:36 am

Re: MOD54415 DSPI CS Assertion

Post by mpgramlich »

Update:

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

-Matt
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: MOD54415 DSPI CS Assertion

Post 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
Dan Ciliske
Project Engineer
Netburner, Inc
mpgramlich
Posts: 6
Joined: Mon Apr 06, 2015 8:36 am

Re: MOD54415 DSPI CS Assertion

Post 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
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: MOD54415 DSPI CS Assertion

Post 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
Dan Ciliske
Project Engineer
Netburner, Inc
mpgramlich
Posts: 6
Joined: Mon Apr 06, 2015 8:36 am

Re: MOD54415 DSPI CS Assertion

Post 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
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: MOD54415 DSPI CS Assertion

Post by dciliske »

Yes, this is compatible with the Nano. The Nano and Mod share the majority of their peripheral drivers.
Dan Ciliske
Project Engineer
Netburner, Inc
mpgramlich
Posts: 6
Joined: Mon Apr 06, 2015 8:36 am

Re: MOD54415 DSPI CS Assertion

Post 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
Attachments
24 bit transfer size No DMA
24 bit transfer size No DMA
TEK0005.JPG (118.62 KiB) Viewed 5759 times
24 bit transfer size DMA
24 bit transfer size DMA
TEK0004.JPG (118.69 KiB) Viewed 5759 times
16 bit transfer size DMA
16 bit transfer size DMA
TEK0003.JPG (114.06 KiB) Viewed 5759 times
16 bit transfer size No DMA
16 bit transfer size No DMA
TEK0002.JPG (117.5 KiB) Viewed 5759 times
1000hz 8 bit transfer size No DMA
1000hz 8 bit transfer size No DMA
TEK0001.JPG (119.39 KiB) Viewed 5759 times
1000hz 8 bit transfer size DMA
1000hz 8 bit transfer size DMA
TEK0000.JPG (139.86 KiB) Viewed 5759 times
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: MOD54415 DSPI CS Assertion

Post 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
Dan Ciliske
Project Engineer
Netburner, Inc
Post Reply