Hello Everyone
I am playing around with SPI on LPCXpresso802 board. Everything seems OK but there is an unclear code that I try to understand but I could not configure out.
It is in example: lpcxpresso802_spi_interrupt_master.
As the Data transfer Length is setup with 8 bits width, so RXDAT and TXDAT will be handle each single byte. but why does it need casting type (uint16_t) as below?
I have connected to external SPI chip (AS3933), if no casting type, then read command sometime did not get right value.
Here is the origial interrupt code
void SPI_MASTER_IRQHandler(void)
{
/* Check if data is ready in RX register. */
if ((SPI_GetStatusFlags(EXAMPLE_SPI_MASTER) & kSPI_RxReadyFlag))
{
rxBuffer[BUFFER_SIZE - rxIndex] = SPI_ReadData(EXAMPLE_SPI_MASTER);
rxIndex--;
}
/* Write data to TX regsiter if TX register is ready. */
if ((SPI_GetStatusFlags(EXAMPLE_SPI_MASTER) & kSPI_TxReadyFlag) && (txIndex != 0U))
{
/* If this is the last byte to send. */
if (1U == txIndex)
{
/* Add end of transfer configuration. */
SPI_WriteConfigFlags(EXAMPLE_SPI_MASTER, kSPI_EndOfTransfer);
SPI_WriteData(EXAMPLE_SPI_MASTER, txBuffer[BUFFER_SIZE - txIndex]);
}
else
{
SPI_WriteData(EXAMPLE_SPI_MASTER, (uint16_t)(txBuffer[BUFFER_SIZE - txIndex]));
}
txIndex--;
}
/* If no data to be transferred, disable the interrupt. */
if ((txIndex == 0U) && (rxIndex == 0U))
{
slaveFinished = true;
SPI_DisableInterrupts(EXAMPLE_SPI_MASTER, kSPI_RxReadyInterruptEnable);
}
__DSB();
}
Thank you.
Solved! Go to Solution.
Hello Babycat,
- TXDAT is 32 bits register, while the 31:16 are reserved, only 15:0 is DATA part.
-"what could be the difference btw:
TXDAT = 0xFF
and
TXDAT = (uint16_t)(0xFF) = 0x00FF
"
To some machine, when there is no casting, maybe add random data in 15:8, for example 0x10FF, not 0X00FF.
So for rigorous,all the data put to DATA need casting to 16 bits.
Regards,
Alice
Hello Babycat,
Because the DATA in SPI transmitter data register is 16 bits, so no matter the
data transfer length is, we need (uint16_t) as you said.
Regards,
Alice
Hi Yang
Thanks for your reply,
then the question is, why dont we cast it in the if clause?
if (1U == txIndex)
{
/* Add end of transfer configuration. */
SPI_WriteConfigFlags(EXAMPLE_SPI_MASTER, kSPI_EndOfTransfer);
SPI_WriteData(EXAMPLE_SPI_MASTER, txBuffer[BUFFER_SIZE - txIndex]);
}
else
{
SPI_WriteData(EXAMPLE_SPI_MASTER, (uint16_t)(txBuffer[BUFFER_SIZE - txIndex]));
}
Regards
Hello,
I think it will be ok if we also cast it here (uint16_t)( txBuffer[BUFFER_SIZE - txIndex]).
This is the last byte to send, so there should no error even though not cast it.
Regards,
Alice
Hi Alice
TXDAT is a 32bit register,
what could be the difference btw:
TXDAT = 0xFF
and
TXDAT = (uint16_t)(0xFF) = 0x00FF
I am not so clear why casting does its job there? I might be missing something...
Thank you.
Hello Babycat,
- TXDAT is 32 bits register, while the 31:16 are reserved, only 15:0 is DATA part.
-"what could be the difference btw:
TXDAT = 0xFF
and
TXDAT = (uint16_t)(0xFF) = 0x00FF
"
To some machine, when there is no casting, maybe add random data in 15:8, for example 0x10FF, not 0X00FF.
So for rigorous,all the data put to DATA need casting to 16 bits.
Regards,
Alice
Hi Alice
Oh, I understood. I did not know about that, I thought C complier will auto add that extra 00 as its job supposed to.
by the way, in case TXDAT = 0x10FF. If I configured Len = 8 bits, MSB first.
Which byte will be sent out, 10 or FF?
Thank you.