K22F- Problem with DSPI-daisy chain

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

K22F- Problem with DSPI-daisy chain

1,969 Views
sandeepkamath
Contributor I

Hi

I have connected two slaves to my k22f board in daisy chain fashion

SCK-- 20MHz

bus clock 40 Mhz

core clock 40Mhz

SPI interrupt mode

case1:

Each slave will take 32 bits of data. So i am sending total 64 bits of data in total for two slaves. So for 20Mhz clock, 8 bytes of data should take 3.2 us( say 4 to 5 us considering other delays). But i am getting a strange delay after each byte of communication. -[400ns for each byte + some 16us delay] *8 times. 

I am using inbuilt Kinteis  FSL_DSPI_MASTER_DRIVER driver.

When tried with SPI 1,  [where it has got 1 FIFO buffer]

dspi_master_user_config_t masterUserConfig = {
.isChipSelectContinuous = true,
.isSckContinuous = false,
.pcsPolarity = kDspiPcs_ActiveLow,
.whichCtar = kDspiCtar1,
.whichPcs = kDspiPcs0
};

masterDevice.dataBusConfig.bitsPerFrame = 8;
masterDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge; // CPOL = 0 and CPHA = 0
masterDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh;
masterDevice.dataBusConfig.direction = kDspiMsbFirst;

case2:

For SPI 1, with masterDevice.dataBusConfig.bitsPerFrame = 16, it is not working.

Even though the delay has reduced to 10us (which is not acceptable for my requirement), slaves also not responding.

dspi_master_user_config_t masterUserConfig = {
.isChipSelectContinuous = true,
.isSckContinuous = false,
.pcsPolarity = kDspiPcs_ActiveLow,
.whichCtar = kDspiCtar1,
.whichPcs = kDspiPcs0
};

masterDevice.dataBusConfig.bitsPerFrame = 16;
masterDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge; // CPOL = 0 and CPHA = 0
masterDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh;
masterDevice.dataBusConfig.direction = kDspiMsbFirst;

case3:

For SPI 0, [ 4 FIFO]

SCK-- 20MHz

bus clock 60 Mhz

core clock 60 Mhz

dspi_master_user_config_t masterUserConfig = {
.isChipSelectContinuous = true,
.isSckContinuous = false,
.pcsPolarity = kDspiPcs_ActiveLow,
.whichCtar = kDspiCtar1,
.whichPcs = kDspiPcs1
};

masterDevice.dataBusConfig.bitsPerFrame = 16;
masterDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge; // CPOL = 0 and CPHA = 0
masterDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh;
masterDevice.dataBusConfig.direction = kDspiMsbFirst;

In this case, for 64 bit data when i checked in scope, it is getting around 4us.

BUT Not working for me when i connected slaves.

So case 1 is working for me( but with huge delay in between each byte). ideally case 3 should work[ as i can see in scope, 4us for all 64 bit transmission] but it is not working for me when connected salves in daisy chain.

 Can you please help me in finding a possible solution to communicate using daisy chain for 64 bit transmission at 20Mhz clock (operation within 4us).

 

0 Kudos
14 Replies

1,627 Views
sandeepkamath
Contributor I

I have managed to make DSPI (SPI 1) with DMA working @ 20Mhz (8 bits per frame) [8 byte gives the overall delay of 10us though]

Can anyone help with 16 Bits per frame for the same above configuration. 

Library used is kinteis 1.3.0

0 Kudos

1,627 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Firstly, I suggest you use the case 1, because case 1 is working. For the delay issue, I suggest you check the SPIx_CTAR1 register in debugger tools when the K22 is in break state, all the delays are determined by the register. After you checked the register, you can use hal function or write the register directly to change the delay bits.

Hope it can help you.

BR

XiangJun Rong

0 Kudos

1,627 Views
sandeepkamath
Contributor I

Hi,

Thanks for the response.

I Have checked the register. 

pastedImage_1.png

clock freq: 120Mhz

Core clock : 40 Mhz

Bus clock 40 Mhz

SPI clock 40 Mhz

But still between the Multi byte transfer i am getting a delay of ~800ns

for 64 bit transfer, the total time taken sould be ~ 4us

but because of this 800ns delay, i am getting a total time around ~9 us

Can you pls help me to sort this out. 

Timing plays a very critical role in this task( should be 4us). So i am trying to reduce as much delay as possible

Thanks

sandeep

0 Kudos

1,627 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Sandeep,

If the SPI1_CTAR1 register is 0xb800 0000, you can not reduce delay from spi side, the delay between the Multi byte transfer is caused by software. If you do not use SDK and write register directly using interrupt mode, the delay can be reduced i think.

BR

Xiangjun Rong

0 Kudos

1,627 Views
sandeepkamath
Contributor I

Hi,

Interrupt mode is giving more delay. So i used dMA based approach.

Should i re-write the DMA code instead?

0 Kudos

1,627 Views
sandeepkamath
Contributor I

Actually "16 bits per frame " will solve my problem. But i am not able to make the working model with 16 bits/frame for k22f

May i know if there is any reason behind this? k22f doesn't support or SDK driver isn't functioning for 16 bits/frame?

Or am i missing any settings?

0 Kudos

1,627 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

the K22 supports 16 bits per frame, but I suppose that the SDK driver has issue.

BR

Xiangjun Rong

0 Kudos

1,627 Views
sandeepkamath
Contributor I

Hi,

I have one more question regarding SPI0 (with 4 FIFO buffers). 

May i know what modifications i have to do in SDK driver if i have to use SPI0

0 Kudos

1,627 Views
sandeepkamath
Contributor I

Hi Xiangjun,

Oh. Ok.

Is there any temporary fix for that? shall i get any alternative driver for 16 bit frame?

That would be very helpful

Thanks.

sandeep

0 Kudos

1,627 Views
sandeepkamath
Contributor I

Hi,

The earlier perception regarding DMA was wrong.

The kinetis SDK driver for both Interrupt based and DMA will have along delay

For Interrupt:  There is along delay between multi byte

For DMA: The inter transfer delay is long. (Even though the SPI_CTAR register is set to ideal condition(that is no delay))

Then there was no other option than re-writhing the driver. 

with hardly few lines of code( without interrupt, without dspistate, etc). 

Here "cmd" is hardcoded. so that i can reduce the run time instruction.

But in between push and pop operation you need to give some sort of delay (and this is minimum as shown in below "for loop". If the value is below  "10", you  will receive junk data)

DSPI_HAL_WriteCmdDataMastermode(base, cmd|*sendBuffer);
for(uint8_t h=0; h<10; h++);
*receiveBuffer = DSPI_HAL_ReadData(base);

By doing this. For 64 bit transmission, i am getting around 6us.

There is no more optimization i can do in my code

 core clock and bus clock : 60MHz

SPI:  20 Mhz

eclipse optimization level -   -Og

I need to get it exactly at 4us fro 64 bit transfer

I have a question. Is the ARM M4 not capable of handling the SPI speed of 4us?

0 Kudos

1,627 Views
egoodii
Senior Contributor III

You might look at my scope-shot in my reply in:

https://community.nxp.com/message/835801?commentID=835801#comment-835801 

With careful FIFO-handling (and IAR-optimized code!), I can 'just about' keep up with a SPI-clock at CPU_CLK/4 [ideally one incoming, one outgoing SPI-op every 32 CPU cycles in 8-bit SPI mode], including an optional CRC accumulation in 32bit-multiples only.  The key is to keep the TX-FIFO a 'couple transactions ahead' of the RX-stream.  My code does, however, have limitations in allowed transaction sizes, given some of the 'loop unrolling' involved, and because of this TX-FIFO pre-loading.

0 Kudos

1,627 Views
sandeepkamath
Contributor I

By the way, in the above post, Bits per frame is 16

0 Kudos

1,627 Views
sandeepkamath
Contributor I

I would like to go with DMA approach itself,

But problem is

1. Using the existing Kintis driver, i am able to send the data to two slaves in daisy chain. But the received value is garbage

  -sck  20Mhz, bus clock 40 Mhz, 8 bits per frame

2.  If the above problem gets rectified, i would like to  use 16 bits per frame (which is currently not working ) 

0 Kudos

1,627 Views
sandeepkamath
Contributor I

Hi.

An update:

Using DMA, i am able to bring down the time to nearly ~6 to 7 us

I have increased the core clock, and bus clock to 60 MHz.

masterDevice.dataBusConfig.bitsPerFrame = 8

But still i cannot use 16 bits per frame in DMA. 

masterDevice.dataBusConfig.bitsPerFrame = 16

Can anyone help me in using 16 bits per frame for dspi. Am i missing any configuration settings somewhere?

dspi_edma_master_user_config_t edmaMasterUserConfig = {
.isChipSelectContinuous = true,
.isSckContinuous = false,
.pcsPolarity = kDspiPcs_ActiveLow,
.whichCtar = kDspiCtar1,
.whichPcs = kDspiPcs0
};

/* Initialize eDMA driver */
dmaUserConfig.chnArbitration = kEDMAChnArbitrationRoundrobin;
EDMA_DRV_Init(&dmaState, &dmaUserConfig);

edmaDevice.dataBusConfig.bitsPerFrame = 16;
edmaDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge; // CPOL = 0 and CPHA = 0
edmaDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveHigh;
edmaDevice.dataBusConfig.direction = kDspiMsbFirst;

// Initialize master driver.
dspiResult = DSPI_DRV_EdmaMasterInit(DSPI_MASTER_INSTANCE,
&edmaMasterState,
&edmaMasterUserConfig,
&stcdDspiMasterTest);

0 Kudos