status_t I3C_PrivateTransferBlocking(I3C_Type *base, i3c_master_transfer_t *transfer) { assert(NULL != transfer); assert(transfer->subaddressSize <= sizeof(transfer->subaddress)); status_t result = kStatus_Success; i3c_direction_t direction = transfer->direction; i3c_master_state_t masterState = I3C_MasterGetState(base); bool checkDdrState = false; /* Return an error if the bus is already in use not by us. */ checkDdrState = (transfer->busType == kI3C_TypeI3CDdr) ? (masterState != kI3C_MasterStateDdr) : true; if ((masterState != kI3C_MasterStateIdle) && (masterState != kI3C_MasterStateNormAct) && checkDdrState) { return kStatus_I3C_Busy; } /* Clear all flags. */ I3C_MasterClearStatusFlags(base, (uint32_t)kMasterClearFlags); /* Reset fifos. These flags clear automatically. */ base->MDATACTRL |= I3C_MDATACTRL_FLUSHTB_MASK | I3C_MDATACTRL_FLUSHTB_MASK; if (transfer->busType != kI3C_TypeI3CDdr) { direction = (0UL != transfer->subaddressSize) ? kI3C_Write : transfer->direction; } if (0UL == (transfer->flags & (uint32_t)kI3C_TransferNoStartFlag)) { result = I3C_MasterStart(base, transfer->busType, transfer->slaveAddress, direction, direction == kI3C_Write ? 0UL : transfer->dataSize); /* Wait tx fifo empty. */ size_t txCount = 0xFFUL; while (txCount != 0U) { I3C_MasterGetFifoCounts(base, NULL, &txCount); } /* Check if device request wins arbitration. */ if (0UL != (I3C_MasterGetStatusFlags(base) & (uint32_t)kI3C_MasterArbitrationWonFlag)) { return kStatus_I3C_IBIWon; } } result = I3C_MasterStop(base); /* Subaddress, MSB first.*/ if (0U != transfer->subaddressSize) { result = I3C_MasterRepeatedStart(base, transfer->busType, 0x30, direction, 0UL); uint32_t subaddressRemaining = transfer->subaddressSize; while (0UL != subaddressRemaining--) { uint8_t subaddressByte = (uint8_t)((transfer->subaddress >> (8UL * subaddressRemaining)) & 0xFFUL); result = I3C_MasterWaitForTxReady(base, 1U); if ((0UL == subaddressRemaining) && (transfer->direction == kI3C_Read) && (transfer->busType != kI3C_TypeI3CDdr)) { base->MWDATABE = subaddressByte; result = I3C_MasterWaitForComplete(base, false); if (kStatus_Success != result) { return result; } } else { base->MWDATAB = subaddressByte; } } /* Need to send repeated start if switching directions to read.*/ if ((transfer->busType != kI3C_TypeI3CDdr) && (0UL != transfer->dataSize) && (transfer->direction == kI3C_Read)) { result = I3C_MasterRepeatedStart(base, transfer->busType, transfer->slaveAddress, kI3C_Read, transfer->dataSize); if (kStatus_Success != result) { return result; } } } /* Transmit data. */ if ((transfer->direction == kI3C_Write) && (transfer->dataSize > 0UL)) { /* Send Data. */ result = I3C_MasterSend(base, transfer->data, transfer->dataSize, transfer->flags); } /* Receive Data. */ else if ((transfer->direction == kI3C_Read) && (transfer->dataSize > 0UL)) { result = I3C_MasterReceive(base, transfer->data, transfer->dataSize, transfer->flags); } else { /* Empty else to fix MISRA 15.7*/ } return result; }