in IndustrialDeviceController/Software/MT3620_IDC_RTApp/lib/I2CMaster.c [477:567]
static void I2CMaster_IRQ(Platform_Unit unit)
{
unsigned id = I2CMaster_UnitToID(unit);
if (id >= MT3620_I2C_COUNT) {
return;
}
MT3620_I2C_FIELD_WRITE(id, int_ctrl, mm_int_sta, true);
I2CMaster* handle = &context[id];
// This should never happen
if (!handle->open) {
return;
}
int32_t status = ERROR_NONE;
if ((MT3620_I2C_FIELD_READ(id, mm_ack_val, mm_ack_id) & 0x1) != 0) {
status = ERROR_I2C_ADDRESS_NACK;
} else if (MT3620_I2C_FIELD_READ(id, mm_status, mm_arb_had_lose)) {
MT3620_I2C_FIELD_WRITE(id, mm_status, mm_arb_had_lose, 1);
status = ERROR_I2C_ARBITRATION_LOST;
}
uintptr_t txRemain = 0;
uintptr_t rxRemain = 0;
if (handle->useDMA) {
MT3620_DMA_FIELD_WRITE(MT3620_I2C_DMA_TX(id), start, str, false);
MT3620_DMA_FIELD_WRITE(MT3620_I2C_DMA_RX(id), start, str, false);
txRemain += mt3620_dma[MT3620_I2C_DMA_TX(id)].rlct;
rxRemain += mt3620_dma[MT3620_I2C_DMA_RX(id)].rlct;
} else {
unsigned i;
for (i = 0; i < handle->count; i++) {
uint8_t *readData = handle->transfer[i].readData;
if (readData) {
unsigned j;
for (j = 0; j < handle->transfer[i].length; j++) {
if (!MT3620_I2C_FIELD_READ(id, mm_fifo_status, rx_fifo_emp)) {
readData[j] = mt3620_i2c[handle->id]->mm_fifo_data;
} else {
rxRemain++;
}
}
}
}
}
mt3620_i2c_fifo_status_t fifo_status = { .mask = mt3620_i2c[id]->mm_fifo_status };
mt3620_i2c_fifo_ptr_t fifo_ptr = { .mask = mt3620_i2c[id]->mm_fifo_ptr };
bool txClear = !fifo_status.tx_fifo_emp;
if (txClear) {
txRemain += (fifo_status.tx_fifo_full ? MT3620_I2C_TX_FIFO_DEPTH
: (fifo_ptr.tx_fifo_wptr - fifo_ptr.tx_fifo_rptr));
}
bool rxClear = !fifo_status.rx_fifo_emp;
if (rxClear) {
rxRemain += (fifo_status.rx_fifo_full ? MT3620_I2C_RX_FIFO_DEPTH
: (fifo_ptr.rx_fifo_wptr - fifo_ptr.rx_fifo_rptr));
}
if (txClear || rxClear) {
fifoClearMaster(id, txClear, rxClear);
if (status == ERROR_NONE) status = ERROR_I2C_TRANSFER_INCOMPLETE;
}
uintptr_t txCount = (txRemain > handle->txQueued
? 0 : (handle->txQueued - txRemain));
uintptr_t rxCount = (rxRemain > handle->rxQueued
? 0 : (handle->rxQueued - rxRemain));
uintptr_t dataCount = (txCount + rxCount);
if (handle->callback) {
handle->callback(status, dataCount);
} else if (handle->callbackUser) {
handle->callbackUser(status, dataCount, handle->userData);
}
handle->error = (status != ERROR_NONE);
handle->transfer = NULL;
handle->count = 0;
handle->txQueued = 0;
handle->rxQueued = 0;
handle->callback = NULL;
handle->callbackUser = NULL;
handle->userData = NULL;
}