AnsweredAssumed Answered

K17 SPI with DMA - First byte incorrect

Question asked by joe hinkle on Sep 25, 2017
Latest reply on Sep 27, 2017 by Kerry Zhou

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
      }

      SPI1_C2 = SPI_C2_RXDMAE_MASK;

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

// 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
         DMA_DSR_BCR0 |= DMA_DSR_BCR_DONE_MASK;

 

      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.

 

Thanks.

 

Joe

Outcomes