AnsweredAssumed Answered

Issues with DMA mode SPI on FDRM-K22F Board

Question asked by Rose Wall on Apr 14, 2016

I seem to have encountered a bug in the DMA mode SPI where it only transfers the first five bytes of data and still reports a 'success'.

To reproduce the issue I wired the SPI0_out to SPI0_in (connect pins 11 and 16 on the J1 header) and created the following test project:

 

Create new Kinetis SDK 1.x Project

          Select the K22FN512xxx12 processor (eventually I will be using a custom board so I didn't want to start with all the premade board files)

          Select Processor Expert and hardware configuration

 

From the Components Library add fsl_dspi and fsl_debug_console to the project.

 

Open the fsl_clock_manager in the component inspector:

          In properties>clock management>clock settings>clock sources> Select External Oscillator 0 and then external crystal as an additional clock source

          In properties>clock management>clock settings>clock configurations>MCG settings select PEE mode and MCG output to be 80 MHz, Reference clock source should be 'External Clock'

           In properties>clock management>clock settings>clock configurations>System Clocks set core clock and bus clock to 40 MHz, External bus clock to be 20 MHz and the Flash clock to be 10 MHz

 

Open fsl_dspi in the component inspector:

          In properties select "device: SPI0" and "component mode: DMA"

          In properties>configuration list set the clock speed to be 20 MHz

          In properties>pins:

                    input: CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS/FBa_AD8

                    output: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FBa_AD9/I2S0_MCLK

                    clock: PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FBa_AD10/CMP0_OUT/FTM0_CH2

                    chip select: ADC0_SE4b/CMP1_IN0/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/...

 

Open fsl_debug_console in the component inspector:

          Device: UART1

          RxD: ADC1_SE5a/PTE1/LLWU_P0/SPI1_SOUT/UART1_RX/I2C1_SCL/SPI1_SIN

          TxD: ADC1_SE4a/PTE0/CLKOUT32K/SPI1_PCS1/UART1_TX/I2C1_SDA/RTC_CLKOUT

 

Whew! Ok now generate processor expert code and within your generated main.c put the following code where it says "put your code here":

  /* Write your code here */   /* For example: for(;;) { } */   uint8_t spiDataOut[128]={0},spiDataIn[128]={0}; //initialize data buffers   for(int i = 0; i<128; i++) { //put nonzero values in buffer that will be sent     spiDataOut[i] = i;   }   DSPI_DRV_EdmaMasterTransferBlocking(dspiCom1_IDX, NULL, spiDataOut, spiDataIn, 128, 10000);   for(int j = 0; j < 128; j++) {     debug_printf("\r\nsent: %d received: %d\r\n", spiDataOut[j], spiDataIn[j]); //print data   }   debug_printf("\n\n");   /*** Don't write any code pass this line, or it will be deleted during code generation. ***/

 

The terminal data then looks like this:

sent: 0 received: 0

sent: 1 received: 1

sent: 2 received: 2

sent: 3 received: 3

sent: 4 received: 4

sent: 5 received: 0

sent: 6 received: 0

sent: 7 received: 0

sent: 8 received: 0

sent: 9 received: 0

sent: 10 received: 0

sent: 11 received: 0

...

sent: 127 received: 0

 

If you do the same thing with interrupt mode SPI:

     Open fsl_dspi in the component inspector and then change component mode to Interrupt

     Change line 7 in the code above to:

DSPI_DRV_MasterTransferBlocking(dspiCom1_IDX, NULL, spiDataOut, spiDataIn, 128, 10000);

 

sent: 0 received: 0

sent: 1 received: 1

sent: 2 received: 2

sent: 3 received: 3

sent: 4 received: 4

sent: 5 received: 5

sent: 6 received: 6

sent: 7 received: 7

sent: 8 received: 8

sent: 9 received: 9

sent: 10 received: 10

sent: 11 received: 11

...

sent: 127 received: 127

 

Additionally I have tried with the default clock settings and SPI running at only 10 MHz -- same issue.

 

The data transfer call always returns a zero which indicates a successful transfer, for both the successful interrupt based example and the not working dma based example.

 

I also tried with a non blocking transfer and checking the status until it no longer says 'busy' before moving on to the rest of the program, this would return busy once and say it had sent 5 bytes and then return 'success' and say it had then transferred all 128 yet only five were correct, the rest were zeros as above.

 

I also tried playing around with the timeout parameter for the transfer method which didn't appear to have any effect on the number of bytes which were transferred.

Original Attachment has been moved to: dma_bug.zip

Attachments

Outcomes