SPI transfer loses byte when interrupted by PWM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI transfer loses byte when interrupted by PWM

Jump to solution
1,031 Views
Kratz
Contributor IV

MKE02Z64 has PWM, PIT Timer and SPI transfer start interrupts.   I am using a scope with a SPI bus module to see the transfers.  I can look at the last trasfer of memory when a failures occurs because of a CRC failure trap.  Most transfers happen as they should.  Occasionally it appers that when a SPI transfer gets interrupted by PWM I assume, my scope shows the slave SPI sent the correct number of bytes, but the internal CPU receive memory array shows one byte was missed or overwritten.  The SPI code was written using processor expert. 

I would appreciate any insights into what could be going on?   @This is the last problem before releasing the code, so I would really appreciate your help. 

/*
** ===================================================================
**     Method      :  LCD_SPI_ReceiveBlock (component SPIMaster_LDD)
*/
/*!
**     @brief
**         This method specifies the number of data to receive. The
**         method returns ERR_BUSY until the specified number of
**         characters is received. The method [CancelBlockReception]
**         can be used to cancel a running receive operation. If a
**         receive operation is not in progress (the method was not
**         called or a previous operation has already finished) all
**         received characters will be lost without any notification.
**         To prevent the loss of data call the method immediately
**         after the last receive operation has finished (e.g. from the
**         [OnBlockReceived] event). This method finishes immediately
**         after calling it - it doesn't wait the end of data reception.
**         Use event [OnBlockReceived] to check the end of data
**         reception or method GetReceivedDataNum to check the state of
**         receiving.
**     @param
**         DeviceDataPtr   - Device data structure
**                           pointer returned by [Init] method.
**     @param
**         BufferPtr       - Pointer to A buffer where
**                           received characters will be stored.
**     @param
**         Size            - Size of the block
**     @return
**                         - Error code, possible codes:
**                           ERR_OK - OK
**                           ERR_SPEED - This device does not work in
**                           the active clock configuration
**                           ERR_DISABLED - Component is disabled
**                           ERR_BUSY - The previous receive request is
**                           pending
*/
/* ===================================================================*/

LDD_TError LCD_SPI_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size)
{
  if (((LCD_SPI_TDeviceDataPtr)DeviceDataPtr)->InpDataNumReq != 0x00U) { /* Is the previous receive operation pending? */
    return ERR_BUSY;                   /* If yes then error */
  }
  /* {Default RTOS Adapter} Critical section begin, general PE function is used */
  EnterCritical();
  ((LCD_SPI_TDeviceDataPtr)DeviceDataPtr)->InpDataPtr = (uint8_t*)BufferPtr; /* Store a pointer to the input data. */
  ((LCD_SPI_TDeviceDataPtr)DeviceDataPtr)->InpDataNumReq = Size; /* Store a number of characters to be received. */
  ((LCD_SPI_TDeviceDataPtr)DeviceDataPtr)->InpRecvDataNum = 0x00U; /* Set number of received characters to zero. */
  if ((SPI_PDD_ReadStatusReg(SPI1_BASE_PTR) & SPI_PDD_RX_BUFFER_FULL) != 0U) {
    (void)SPI_PDD_ReadData8bit(SPI1_BASE_PTR); /* Dummy read of the data register */
  }
  ((LCD_SPI_TDeviceDataPtr)DeviceDataPtr)->SerFlag &= (uint8_t)(~(uint8_t)BLOCK_RECEIVED); /* Clear data block received flag */
  SPI_PDD_EnableInterruptMask(SPI1_BASE_PTR, SPI_PDD_RX_BUFFER_FULL_OR_FAULT); /* Enable Rx buffer full interrupt */
  /* {Default RTOS Adapter} Critical section end, general PE function is used */
  ExitCritical();
  return ERR_OK;                       /* OK */
}

1 Solution
868 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi KEVIN KRATZER,

   If the SPI data is very important, you can set the SPI transfer priority is more higher, just make sure other interrupt won't influence the SPI byte lost problem.

   BTW, the interrupt service code should as small as possible, otherwise, if the SPI is receiving the data, but the interrupt break it, and caused a lot of times, that time is more than the SPI byte receiving, then it will cause some SPI byte lost problem.

   Another way, if the SPI master didn't receive the correct data frame, it also can tell the SPI slave to send the data again.

Wish it helps you!

If you still have questions about it, please kindly let me know.

Have a great day,
Kerry

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

View solution in original post

3 Replies
869 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi KEVIN KRATZER,

   If the SPI data is very important, you can set the SPI transfer priority is more higher, just make sure other interrupt won't influence the SPI byte lost problem.

   BTW, the interrupt service code should as small as possible, otherwise, if the SPI is receiving the data, but the interrupt break it, and caused a lot of times, that time is more than the SPI byte receiving, then it will cause some SPI byte lost problem.

   Another way, if the SPI master didn't receive the correct data frame, it also can tell the SPI slave to send the data again.

Wish it helps you!

If you still have questions about it, please kindly let me know.

Have a great day,
Kerry

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

868 Views
Kratz
Contributor IV

Kerry Thanks for replying. I will see about slimming down the SPI code. The control is driving an inverter, so it has to have the highest priority interrrupts. Thanks for clarifying the problem.  I was suspecting the interrupt, but thought it would not happen. Also could not find any other posts on this topic.  I cannot be the first. 

If I had a CRC failure because of the lost data, I could request the last transfer ahead of the scheduled transfer. What do you think.  Do you have any better ideas?  

0 Kudos
868 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi KEVIN KRATZER,

   You are welcome.

   About the CRC failure, my thought is when the spi master receive the data CRC is failure, then send the data request to the SPI slave again, just request the new data again, until the CRC is correct.

Wish it helps you!

If you still have questions about it, please kindly let me know.

Have a great day,
Kerry

 

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

1 of 1 people found this helpful