AnsweredAssumed Answered

Processor Expert SPI driver issue

Question asked by Sudeep Chandrasekaran on Jul 27, 2019
Latest reply on Aug 11, 2019 by Prajwal B V

MCU: MK20DX256

Code warrior: 10.6

I am using processor expert to generate SPI driver for our project. The SPI driver is used to communicate with a flash chip. The chip select of the flash chip is pulled high(active low) when a transaction(all bytes are sent) with the flash is over. We are using the 'OnBlockSent' event by the PE generated code to disable the chip select pin. We have observed that the 'OnBlockSent' event is generated before all bytes are transmitted in the SPI line. We tried diving into the generated code to see if any thing is wrong, we observed that the 'OnBlockSent ' is immediately called after the last byte of the requested sent block is put to the H/W buffer. This means when the 'OnBlockSent' event is called there could be one byte in the SPI PISO to be transmitted and another pending byte in the hardware buffer(our hardware buffer size is 1).  Below is the H/W buffer configuration:

 

 

Below is the ISR implementation where we observed the behavior:

 

PE_ISR(SM1_Interrupt)
{
/* {Default RTOS Adapter} ISR parameter is passed through the global variable */
SM1_TDeviceDataPtr DeviceDataPrv = INT_SPI1__DEFAULT_RTOS_ISRPARAM;
uint32_t StatReg = SPI_PDD_GetInterruptFlags(SPI1_BASE_PTR); /* Read status register */
uint16_t Data; /* Temporary variable for data */

if ((StatReg & SPI_PDD_RX_FIFO_OVERFLOW_INT) != 0U) { /* Is any error flag set? */
SPI_PDD_ClearInterruptFlags(SPI1_BASE_PTR,SPI_PDD_RX_FIFO_OVERFLOW_INT); /* Clear error flags */
}
if ((StatReg & SPI_PDD_RX_FIFO_DRAIN_INT_DMA) != 0U) { /* Is any char in HW buffer? */
Data = (uint16_t)SPI_PDD_ReadPopRxFIFOReg(SPI1_BASE_PTR); /* Read character from receiver */
SPI_PDD_ClearInterruptFlags(SPI1_BASE_PTR,SPI_PDD_RX_FIFO_DRAIN_INT_DMA); /* Clear Rx FIFO drain flags */
if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the receive block operation pending? */
*(DeviceDataPrv->InpDataPtr++) = (uint8_t)Data; /* Put a character to the receive buffer and increment pointer to receive buffer */
DeviceDataPrv->InpRecvDataNum++; /* Increment received char. counter */
if (DeviceDataPrv->InpRecvDataNum == DeviceDataPrv->InpDataNumReq) { /* Is the requested number of characters received? */
DeviceDataPrv->InpDataNumReq = 0x00U; /* If yes then clear number of requested characters to be received. */
SM1_OnBlockReceived(DeviceDataPrv->UserData);
}
}
}
if ((StatReg & SPI_PDD_TX_FIFO_FILL_INT_DMA) != 0U) { /* Is HW buffer empty? */
if (DeviceDataPrv->OutSentDataNum < DeviceDataPrv->OutDataNumReq) { /* Is number of sent characters less than the number of requested incoming characters? */
DeviceDataPrv->OutSentDataNum++; /* Increment the counter of sent characters. */
SPI_PDD_WriteMasterPushTxFIFOReg(SPI1_BASE_PTR, (uint32_t)(*((uint8_t *)DeviceDataPrv->OutDataPtr++) | DeviceDataPrv->TxCommand)); /* Put a character with command to the transmit register and increment pointer to the transmitt buffer */
if (DeviceDataPrv->OutSentDataNum == DeviceDataPrv->OutDataNumReq) {
DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */
SM1_OnBlockSent(DeviceDataPrv->UserData);
}
} else {
SPI_PDD_DisableDmasInterrupts(SPI1_BASE_PTR, SPI_PDD_TX_FIFO_FILL_INT_DMA); /* Disable TX interrupt */
}
SPI_PDD_ClearInterruptFlags(SPI1_BASE_PTR,SPI_PDD_TX_FIFO_FILL_INT_DMA); /* Clear Tx FIFO fill flags */
}
}

 

Question:

 

1. Isn't this implementation wrong, shouldn't 'OnBlockSent' be called after all bytes are put to the SPI line ?

2. What is the way we could figure out all SPI bytes are transmitted onto the SPI bus ?

Outcomes