I am using the MPC5775B microcontroller with an SPI EEPROM. In my application, CAN messages are received continuously using interrupts, and SPI communication with the EEPROM is also interrupt-driven.
Under heavy CAN bus traffic (e.g., five CAN IDs are received every 1 ms), any EEPROM read operation starts timing out. I am using the DSPI_MasterTransferBlocking() API with a timeout of 10 ms. I also tried increasing the timeout value significantly, but the read operation still fails.
Interestingly, the behavior depends on the amount of data being read. When I attempt to read only a few bytes from the EEPROM, the SPI transfer times out. However, when I read an entire EEPROM page (256 bytes), the read operation completes successfully.
I also observed that if CAN traffic is stopped, the EEPROM read operation succeeds without any issues. I verified the interrupt priorities, and both the CAN and SPI interrupts are configured with the same priority level (priority 0).
I would like to understand:
Why do small SPI EEPROM read operations time out under heavy CAN interrupt load, while larger (256-byte) page reads complete successfully?
Could this be related to interrupt starvation, the implementation of DSPI_MasterTransferBlocking(), or the interaction between the CAN and DSPI interrupt handlers?
Is there any known limitation or recommended configuration for using interrupt-driven DSPI transfers concurrently with high-frequency CAN interrupts on the MPC5775B?
Additionally i debugged the issue by placing break points inside the DSPI_MasterTransferBlocking(),during the debug
status_t DSPI_MasterTransferBlocking(dspi_instance_t instance,
const void * sendBuffer,
void * receiveBuffer,
uint16_t frames,
uint32_t timeout)
{
DEV_ASSERT((uint32_t)instance < (SPI_INSTANCE_COUNT + DSPI_INSTANCE_COUNT));
status_t status;
dspi_state_t * state = DSPI_state[instance];
if (state->status == DSPI_IN_PROGRESS)
{
return STATUS_BUSY;
}
state->isBlocking = true;
(void)OSIF_SemaWait(&(state->dspiSemaphore), 0);
status = DSPI_MasterTransfer(instance, sendBuffer, receiveBuffer, frames);
if (status == STATUS_SUCCESS)
{
status = OSIF_SemaWait(&(state->dspiSemaphore), timeout);
if (status != STATUS_SUCCESS)
{
(void)DSPI_AbortTransfer(instance);
state->status = DSPI_TRANSFER_FAIL;
return status;
}
}
return STATUS_SUCCESS;
}
dspi transfer status getting success, but "OSIF_SemaWait" after dspi transfer getting timeout.