AnsweredAssumed Answered

Trouble using SPI GetBlockSentStatus()

Question asked by Daniel Nagy on May 3, 2016

Dear Support and Forum Members,

 

I am working on a project using a Kinetis K64F microcontroller and am having some trouble detecting the end of an SPI transmission. I use Kinetis Design Studio 3.2 and Processor Expert. The microcontroller, an MK64FN1M0VLL12 is on a custom PCB. What I am experiencing is the following:

 

I would like send 3 bytes on SPI, where the master is the microcontroller. I set up an output buffer and call the PEx function SPI_SendBlock(). Then I would like to block the program until the transmission of all 3 bytes is done. For this purpose, I call the PEx function SPI_GetBlockSentStatus() in a loop and exit it when the function returns true. However, the function seems to return true well before the transmission completes. In fact, it returns true right after the first byte has been shifted out.

 

The main() function looks like this:

#define BUFLEN 3

int main(void)
{
// SPI output buffer
uint8 outbuf[BUFLEN];

/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
PE_low_level_init();
/*** End of Processor Expert internal initialization.                    ***/

// Fill in SPI output buffer
outbuf[0]=0xAA;
outbuf[1]=0x00;
outbuf[2]=0xFF;

// Initialize TestOut pin to 0
TestOut_PutVal(NULL, 1);
TestOut_PutVal(NULL, 0);

// Start SPI transmission
SPI_SendBlock(SPI_DeviceData, outbuf, BUFLEN);

// Wait until all data is sent
while (!SPI_GetBlockSentStatus(SPI_DeviceData));

// Assert TestOut pin
TestOut_PutVal(NULL, 1);

// Wait forever
for(;;);

/*** Don't write any code pass this line, or it will be deleted during code generation. ***/
  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
  #ifdef PEX_RTOS_START
    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
  #endif
  /*** End of RTOS startup code.  ***/
  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;){}
  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

 

I am using a BitIO component (named TestOut) to determine when the program passes the line "while (!SPI_GetBlockSentStatus(SPI_DeviceData));". Capturing the signals with an oscilloscope, I see this:

SPI.png

It can be seen that data transmission works fine, but the TestOut pin (blue channel on the oscilloscope) is asserted after the first byte has been transmitted on the SPI bus.

 

My question would be: Am I misunderstanding the aim of the function SPI_GetBlockSentStatus()? Shouldn't it indicate the very end of the SPI transmission? Could you help me finding out what I am doing wrong?

 

Some additional information:

  • I have reproduced this phenomenon on an FRDM-K22F board with the very same code. The issue there is similar, although TestOut is asserted a little later (during the transmission of the second SPI byte).
  • I have been using SPI_GetBlockReceivedStatus() successfully. There, logical true is only returned, once all of the bytes have been received.
  • Instead of using SPI_GetBlockSentStatus(), I have tried setting a flag in the event function SPI_OnBlockSent(), but the results were exactly the same as with the original method.
  • Here is a similar thread, but no solution was found there, unfortunately: K70 SPI transmission end detection?
  • I am attaching the project for both the custom board with the K64F and the one for the FRDM-K22F board.

 

I really appreciate your help. Thanks and regards

Daniel

Original Attachment has been moved to: K64F_custom_board_SPIStatusTest.zip

Original Attachment has been moved to: FRDM_K22F_SPIStatusTest.zip

Outcomes