-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
In the following SPI RX FIFO consumption while-loop:
embeddedsw/XilinxProcessorIPLib/drivers/spi/src/xspi.c
Lines 746 to 783 in 1bb19ac
| while ((StatusReg & XSP_SR_RX_EMPTY_MASK) == 0) { | |
| Data = XSpi_ReadReg(InstancePtr->BaseAddr, | |
| XSP_DRR_OFFSET); | |
| if (DataWidth == XSP_DATAWIDTH_BYTE) { | |
| /* | |
| * Data Transfer Width is Byte (8 bit). | |
| */ | |
| if(InstancePtr->RecvBufferPtr != NULL) { | |
| *InstancePtr->RecvBufferPtr++ = | |
| (u8)Data; | |
| } | |
| } else if (DataWidth == | |
| XSP_DATAWIDTH_HALF_WORD) { | |
| /* | |
| * Data Transfer Width is Half Word | |
| * (16 bit). | |
| */ | |
| if (InstancePtr->RecvBufferPtr != NULL){ | |
| *(u16 *)InstancePtr->RecvBufferPtr = | |
| (u16)Data; | |
| InstancePtr->RecvBufferPtr += 2; | |
| } | |
| } else if (DataWidth == XSP_DATAWIDTH_WORD) { | |
| /* | |
| * Data Transfer Width is Word (32 bit). | |
| */ | |
| if (InstancePtr->RecvBufferPtr != NULL){ | |
| *(u32 *)InstancePtr->RecvBufferPtr = | |
| Data; | |
| InstancePtr->RecvBufferPtr += 4; | |
| } | |
| } | |
| InstancePtr->Stats.BytesTransferred += | |
| (DataWidth >> 3); | |
| ByteCount -= (DataWidth >> 3); | |
| StatusReg = XSpi_GetStatusReg(InstancePtr); | |
| } |
As this function does not mandate the parameter ByteCount to be divisible by {1, 2, 4}-byte. It is possible that the caller can pass something like 5-byte to transmit/receive. If this is the case, then, when ByteCount (remaining bytes to receive) is nearing zero, and the DataWidth is not of XSP_DATAWIDTH_BYTE, a read can potentially consumes invalid byte(s).
Instead, would it be more robust to do something like "always test the remaining bytes to receive, and switch to XSP_DATAWIDTH_BYTE when ByteCount is less than the preset DataWidth" ? Or, we should simply add a "divisible by {1, 2, 4}-byte" check at function prologue?