AnsweredAssumed Answered

LPC5528 SPI FIFOWR controlbit issue

Question asked by Rik Vugteveen on Jul 7, 2020
Latest reply on Aug 4, 2020 by Rik Vugteveen

For the project I am working on we are using multiple SPI peripherals. I am currently working on a driver that meets up to our abstraction layer written in C++ but I encounter an issue when trying to exchange data on the SPI bus. All measurements are done on the LPC5528 processor and I use FlexComm8 for my SPI interface.

 

For the input of the exchangeBytes function i use the following data:

uint8_t dataTx[10];
uint8_t dataRx[10];

for(uint32_t i = 0; i < 10; i++)
{
dataTx[i] = i;
dataRx[i] = 0;
}

System::spiFPGA.open();
System::spiFPGA.exchangeBytes(dataTx, dataRx, 10);
System::spiFPGA.close();

 

When I read the user manual for the SPI interfaces the FIFO write data register documentation describes:

Byte, half-word or word writes to FIFOWR will push the data and control bits into the FIFO.
Word writes with the upper half-word of 0, byte writes or half-word writes to FIFOWR will
push the data and the current control bits, into the FIFO. Word writes with a non-zero
upper half-word will modify the control bits before pushing them onto the stack.

The issue I encounter is the unexpected behavior when not always writing the control bits to the FIFO.

The code below shows the blocking exchange function code that is use and which results in a valid SPI transfer:

 

SpiMasterBase::SpiResult SpiMasterDriver::exchangeBytes(uint8_t *in, uint8_t *out, uint32_t nrOfBytes)
{
SpiMasterBase::SpiResult result = SpiMasterBase::SPI_SUCCESS;

uint32_t rxCount = 0;
uint32_t txCount = 0;

while((rxCount < nrOfBytes) || (txCount < nrOfBytes))
{
if((rxCount < nrOfBytes) && (ports[PORT].peripheral->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK)) // Check if there is data in the RX FIFO
{
// There is data in the rx fifo, read the next byte.
out[rxCount++] = ports[PORT].peripheral->FIFORD;
}
else if((txCount < nrOfBytes) && (ports[PORT].peripheral->FIFOSTAT & SPI_FIFOSTAT_TXNOTFULL_MASK)) // Check if there is space in the TX FIFO
{
if(0 < txCount)
{
ports[PORT].peripheral->FIFOWR = in[txCount++] + config;
}
else
{
ports[PORT].peripheral->FIFOWR = in[txCount++] + config;
}
}
else
{
// Nothing to do now. Wait for data in the Rx FIFO or an empty space in the tx FIFO
}
}

return result;
}

 

The code above works like a charm because it always writes the control bits. The result on the SPI output signals is

shown in the image blow.

 

Valid communication

 

When I change the code to:

 

SpiMasterBase::SpiResult SpiMasterDriver::exchangeBytes(uint8_t *in, uint8_t *out, uint32_t nrOfBytes)
{
SpiMasterBase::SpiResult result = SpiMasterBase::SPI_SUCCESS;

uint32_t rxCount = 0;
uint32_t txCount = 0;

while((rxCount < nrOfBytes) || (txCount < nrOfBytes))
{
if((rxCount < nrOfBytes) && (ports[PORT].peripheral->FIFOSTAT & SPI_FIFOSTAT_RXNOTEMPTY_MASK)) // Check if there is data in the RX FIFO
{
// There is data in the rx fifo, read the next byte.
out[rxCount++] = ports[PORT].peripheral->FIFORD;
}
else if((txCount < nrOfBytes) && (ports[PORT].peripheral->FIFOSTAT & SPI_FIFOSTAT_TXNOTFULL_MASK)) // Check if there is space in the TX FIFO
{
if(0 < txCount)
{
ports[PORT].peripheral->FIFOWR = in[txCount++];// + config;
}
else
{
ports[PORT].peripheral->FIFOWR = in[txCount++] + config;
}
}
else
{
// Nothing to do now. Wait for data in the Rx FIFO or an empty space in the tx FIFO
}
}

return result;
}

 

The control bits should not be modified if I am not mistaking and thus the result should be the same. Unfortunately I get an unexpected output signal on the SPI output.

 

Invalid communication

 

The first byte is exchanged correctly but from the second byte the data is not correct anymore and even the clock speed seems to be changed which is totally unexpected to me because there is no option for this in the control bits.   

I know I could always add the control bits and forget about the issue but I do not like to keep unexpected behavior in my code and forget about it I would like to know what I am doing wrong.

Outcomes