in IndustrialDeviceController/Software/MT3620_IDC_RTApp/lib/SPIMaster.c [465:541]
static bool SPIMaster_TransferGlobAppend(
const SPITransfer *transfer,
uint32_t count,
SPIMaster_TransferGlob *glob)
{
// If next transfer is a write but the one after involves a read, we don't glob it
// as we need to glob a read onto a write due to hardware limitations.
if (transfer[0].writeData && !transfer[0].readData && (count >= 2)) {
if (transfer[1].writeData && transfer[1].readData) {
return false;
}
}
// We can't append a write/duplex to a half-duplex read.
if ((glob->type == SPI_MASTER_TRANSFER_READ) && transfer->writeData) {
return false;
}
#ifdef SPI_ALLOW_TRANSFER_WRITE
// We can't append a read/duplex to a half-duplex write.
if ((glob->type == SPI_MASTER_TRANSFER_WRITE) && transfer->readData) {
return false;
}
#endif // #ifdef SPI_ALLOW_TRANSFER_WRITE
unsigned payloadLimit;
switch (glob->type) {
case SPI_MASTER_TRANSFER_FULL_DUPLEX:
payloadLimit = MT3620_SPI_BUFFER_SIZE_FULL_DUPLEX;
break;
case SPI_MASTER_TRANSFER_READ:
payloadLimit = MT3620_SPI_BUFFER_SIZE_HALF_DUPLEX;
break;
case SPI_MASTER_TRANSFER_WRITE:
// We must reserve the last byte to set the MOSI idle level high.
// This is due to a bug in the MT3620 SPI interface.
payloadLimit = MT3620_SPI_BUFFER_SIZE_HALF_DUPLEX - 1;
break;
default:
return false;
}
if ((glob->payloadLen + transfer->length) > payloadLimit) {
#ifdef SPI_ALLOW_TRANSFER_WRITE
if ((glob->type == SPI_MASTER_TRANSFER_FULL_DUPLEX) && !transfer->readData) {
// Check if this transfer would overflow half-duplex glob.
if ((glob->payloadLen + glob->opcodeLen + transfer->length) > (
MT3620_SPI_BUFFER_SIZE_HALF_DUPLEX - 1)) {
return false;
}
// Check if full-duplex glob contains reads.
unsigned t;
for (t = 0; t < glob->transferCount; t++) {
if (glob->transfer[t].readData) {
return false;
}
}
// If a full-duplex glob only contains writes, make it a write glob.
glob->type = SPI_MASTER_TRANSFER_WRITE;
glob->payloadLen += glob->opcodeLen;
glob->opcodeLen = 0;
} else
#endif //#ifdef SPI_ALLOW_TRANSFER_WRITE
{
return false;
}
}
glob->transferCount++;
glob->payloadLen += transfer->length;
return true;
}