AnsweredAssumed Answered

SPI transfer loses byte when interrupted by PWM

Question asked by KEVIN KRATZER on Jul 24, 2019
Latest reply on Jul 28, 2019 by Kerry Zhou

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 */
}

Outcomes