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).
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
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
Hi,
Thanks for the response.
I Have checked the register.
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
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
Hi,
Interrupt mode is giving more delay. So i used dMA based approach.
Should i re-write the DMA code instead?
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?
Hi,
the K22 supports 16 bits per frame, but I suppose that the SDK driver has issue.
BR
Xiangjun Rong
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
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
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?
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.
By the way, in the above post, Bits per frame is 16
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 )
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);