static void SPIMaster_IRQ()

in IndustrialDeviceController/Software/MT3620_IDC_RTApp/lib/SPIMaster.c [709:789]


static void SPIMaster_IRQ(Platform_Unit unit)
{
    unsigned id = SPIMaster_UnitToID(unit);
    if (id >= MT3620_SPI_COUNT) {
        return;
    }

    SPIMaster *handle = &spiContext[id];

    // This should never happen
    if (!handle->open) {
        return;
    }

    if (handle->dma) {
        MT3620_DMA_FIELD_WRITE(MT3620_SPI_DMA_TX(id), start, str, false);
    }

    int32_t status = ERROR_NONE;

    // Clear interrupt flag and the status of the SPI transaction.
    if (!MT3620_SPI_FIELD_READ(id, scsr, spi_ok)) {
        status = ERROR_SPI_TRANSFER_FAIL;
    } else {
        SPIMaster_TransferGlob *glob = &handle->glob[handle->globTransferred];
        if (handle->dma && (mt3620_dma[MT3620_SPI_DMA_TX(id)].rlct != 0)){
            status = ERROR_SPI_TRANSFER_FAIL;
        } else {
            handle->dataCount += (glob->opcodeLen + glob->payloadLen);
        }
    }

    bool final = (status != ERROR_NONE);
    if (status == ERROR_NONE) {
        unsigned g;
        for (g = 0; g < handle->globCount; g++) {
            SPIMaster_TransferGlob *glob = &handle->glob[g];

            unsigned offset = 0;
            unsigned t;
            for (t = 0; t < glob->transferCount; t++) {
                const SPITransfer *transfer = &glob->transfer[t];

                if (transfer->readData) {
                    unsigned sdirOffset = 0;
                    if (glob->type == SPI_MASTER_TRANSFER_FULL_DUPLEX) {
                        sdirOffset = 4;
                    }

                    // Read data out of SDIR.
                    uint8_t *src = (uint8_t*)&mt3620_spi[handle->id]->sdir[sdirOffset];
                    __builtin_memcpy(transfer->readData, &src[offset], transfer->length);
                }

                offset += transfer->length;
                if (t == 0) offset -= glob->opcodeLen;
            }
        }

        handle->globTransferred++;
        final = (handle->globTransferred >= handle->globCount);
        if (!final) {
            status = SPIMaster_TransferGlobQueue(
                handle, &handle->glob[handle->globTransferred]);
            final = (status != ERROR_NONE);
        }
    }

    if (final) {
        if (handle->csEnable && handle->csCallback) {
            handle->csCallback(handle, false);
        }
        if (handle->callback) {
            handle->callback(status, handle->dataCount);
            handle->callback = NULL;
        } else if (handle->callbackUser) {
            handle->callbackUser(status, handle->dataCount, handle->userData);
            handle->callbackUser = NULL;
        }
    }
}