K17 SPI with DMA - First byte incorrect

Showing results for 
Search instead for 
Did you mean: 

K17 SPI with DMA - First byte incorrect

Senior Contributor I

I am using a K17.

Spi is set up for 8 bit data, DMA moving the data.

My data coming in is a repeating sequence (for testing) --- FF 00 00 FF 00 00

The first by in my receive buffer is 00 instead of FF.  It appears the DMA is getting signaled to read an empty SPI RCV register at the beginning of the trans fer process.

Before enabling the DMA transfer, I loop in the RCV status flag to make sure no data is available.

I will present my code below.

Can someone identify my error -- thanks.

SPI INIT function ...... 

void Init_SPI(void)
      SIM_SCGC4 |= SIM_SCGC4_SPI1_MASK; // turn clock on
      PORTB->PCR[16] = PORT_PCR_MUX(2); // SPI_MOSI
      PORTD->PCR[5] = PORT_PCR_MUX(2); // SPI_CLK
      PORTD->PCR[4] = PORT_PCR_MUX(2); // SPI_CS_PS0

      SPI1_C1 = SPI_C1_SPE_MASK | // module enabled
                     SPI_C1_CPHA_MASK | 
                     SPI_C1_CPOL_MASK; // clk idle HI

      SPI1_C2 = SPI_C2_RXDMAE_MASK; // set 8 bit data

      SPI1_C3 = 0;

This function sets up DMA prior to the message packet arriving

void Set_DMA0_For_SPI_Use(void)
      volatile byte B;

      SPI1_C2 = 0;

      while(SPI1_S & SPI_S_SPRF_MASK)
               B = SPI1_DL; // clears out out of sync condition


      DMAMUX0_CHCFG0 = 0; // disable mux channel
      DMAMUX0_CHCFG0 = 18; // SPI1 Rcv

// check to make sure DONE is not set -- if it is -- no SPI operation

      if(DMA_DSR_BCR0 & DMA_DSR_BCR_DONE_MASK) // we need to reset it

      DMA0_Flex_SPI = 1;

      DMA_SAR0 = (dword)&SPI1_DL;

      DMA_DAR0 = (dword)SPI_IN;

      DMA_DSR_BCR0 = Expected_Number_SPI_Bytes;

      DMA_DCR0 = DMA_DCR_EINT_MASK | // enable interrupt at end of xfer
                  DMA_DCR_ERQ_MASK | // Enable Peripheral Request
                  DMA_DCR_CS_MASK | // Cycle Steal .. 1 transfer per spi request
                  DMA_DCR_SSIZE(1) | // 8 bit inc
                  DMA_DCR_DINC_MASK |
                  DMA_DCR_DSIZE(1) | // 8 bit
                  DMA_DCR_START_MASK | // dma request start process
                  DMA_DCR_D_REQ_MASK; // DMA hardware automatically clears the corresponding DCRn[ERQ] bit when the byte count register reaches 0.

Above DMA_DAR0 is set to SPI_IN;

After the DMA interrupt fires -- the data at SPI_IN is a ZERO with the first real incoming data value starting at SPI_IN + 1

Can someone please explain this behavior.



0 Kudos
4 Replies

Senior Contributor I

Thanks Mark:

Your reply is along the lines I was thinking but I would rather have found root-cause, understood what was happening, and fixed it properly.

As it is now, my buffer offset and one additional count to the data amount is working - and consistently providing the correct data.

Unless a support Engineer from NXP can explain this behavior, I'll live with my bandage.

I'm not going to mark your reply as the answer, which for now I think it is the best there is, in hopes NXP will respond.

Thanks Mark.


0 Kudos

NXP TechSupport
NXP TechSupport

Hi Joe,

   Sorry for our later reply, I just take you question, now I will help you about this question.

   I have a question about your issue, what the SPI Slave you are using?

   Did you test the SPI wave, whether the first SPI MISO data is 0x00 or 0xff? This is very important.

   If the SPI bus wave in the first MISO is 0x00, it is your code problem, I will help you check you code. I have test the SPI DMA in the KL series, it works OK.

  Please also give me your SPI waveform with oscilloscope or logic analyzer.

  Please also tell me the full name of your chip.

Have a great day,

Note: If this post answers your question, please click the Correct Answer button. Thank you!

0 Kudos

Senior Contributor I

Let me ask my question a different way since I'm getting no replies with the first.

K17 documentation states that a DMA transfer will take place when the SPI is enabled AND the SPI's SPI_S_SPRF_MASK bit is set in the SPI's S register.

Before kicking off the process I'm making sure there is NO SPI activity and the SPI_S_SPRF_MASK is clear - AND the packet I'm going to acquire has NOT started (I have addition digital handshake signals that guarantee the transfer has not started)

SO --- why is a DMA transfer cycle taking place when no data was acquired by the SPI?

I have placed a bandage on the process by ignoring the first DMA transferred byte and adding one to the DMA count of what is expected.  That is a bandage since root cause it not know and the issue properly identified.

The data transfer comes in packets every 25msec. Each packet contains the same number of bytes and the time to transmit the packet is 5 msec.

The issue has to be with the code setting up the SPI and DMA (which I posted above) but I can't see it -- I'm hoping one of you can see it.

Thanks in advance for any comment.


0 Kudos

Specialist V


I didn't notice anything in your code but I also had a strange behavior when using the PIT to trigger DMA. It is reported here: https://community.nxp.com/thread/442382 

This was on a KL27, whereas the behavior was as expected on K devices (with slightly different PIT and different DMA controller).

I never worked out why the PIT would immediately trigger a DMA transfer when it hadn't fired yet - as if there were a "pending" DMA request that couldn't be cleared. Since I have used the same DMA code in various other applications without such an effect my conclusion was that it was more likely a problem with the trigger source rather than the DMA controller/DMA code itself. That is, something that can't be explained by studying the logic but instead something inherent and not documented, that needs to be respected/ worked around.

Your issue may fall into a similar class. I haven't in fact ever used SPI slave Rx DMA on the K family so can't demonstrate it working as expected at the moment. If you don't find an actual error/explanation I may be able to try later this week, in order to possibly verify the behavior you find.



0 Kudos