status_t I2C_RTOS_Transfer(i2c_rtos_handle_t *handle, i2c_master_transfer_t *transfer) { status_t status; /* Lock resource mutex */ if (xSemaphoreTake(handle->mutex, portMAX_DELAY) != pdTRUE) { return kStatus_I2C_Busy; } status = I2C_MasterTransferNonBlocking(handle->base, &handle->drv_handle, transfer); if (status != kStatus_Success) { xSemaphoreGive(handle->mutex); return status; } /* Wait for transfer to finish */ xSemaphoreTake(handle->semaphore, portMAX_DELAY); /* Unlock resource mutex */ xSemaphoreGive(handle->mutex); /* Return status captured by callback function */ return handle->async_status; }
static int i2c_mcux_transfer(struct device *dev, struct i2c_msg *msgs, u8_t num_msgs, u16_t addr) { I2C_Type *base = DEV_BASE(dev); struct i2c_mcux_data *data = DEV_DATA(dev); i2c_master_transfer_t transfer; status_t status; /* Iterate over all the messages */ for (int i = 0; i < num_msgs; i++) { if (I2C_MSG_ADDR_10_BITS & msgs->flags) { return -ENOTSUP; } /* Initialize the transfer descriptor */ transfer.flags = i2c_mcux_convert_flags(msgs->flags); transfer.slaveAddress = addr; transfer.direction = (msgs->flags & I2C_MSG_READ) ? kI2C_Read : kI2C_Write; transfer.subaddress = 0; transfer.subaddressSize = 0; transfer.data = msgs->buf; transfer.dataSize = msgs->len; /* Start the transfer */ status = I2C_MasterTransferNonBlocking(base, &data->handle, &transfer); /* Return an error if the transfer didn't start successfully * e.g., if the bus was busy */ if (status != kStatus_Success) { return -EIO; } /* Wait for the transfer to complete */ k_sem_take(&data->device_sync_sem, K_FOREVER); /* Return an error if the transfer didn't complete * successfully. e.g., nak, timeout, lost arbitration */ if (data->callback_status != kStatus_Success) { return -EIO; } /* Move to the next message */ msgs++; } return 0; }
static OsStatus_t KL25Z_I2CReadStream(Device_t *dev,uint16_t slaveAddr, uint16_t base_addr, uint8_t addrSize, void *data, uint32_t expectedLen, uint32_t *actualLen, uint16_t timeout) { OsStatus_t ret = kStatusOk; KL25ZI2CDevData_t *dat = (KL25ZI2CDevData_t *)dev->config->devConfigData; KL25ZCustomI2CData_t *custom = (KL25ZCustomI2CData_t *)dev->deviceData; if(custom->busy) { /* device busy, exit */ ret = kDeviceBusy; goto cleanup; } if(!custom->enabled) { /* device already enabled, discard */ ret = kDeviceDisabled; goto cleanup; } if(data == NULL) { ret = kInvalidParam; goto cleanup; } if(expectedLen == 0) { ret = kInvalidParam; goto cleanup; } if(addrSize == 0) { ret = kInvalidParam; goto cleanup; } if(actualLen == NULL) { ret = kInvalidParam; goto cleanup; } custom->busy = true; if(custom->master) { i2c_master_transfer_t xfer; xfer.data = (uint8_t *)data; xfer.dataSize = expectedLen; xfer.direction = kI2C_Read; xfer.slaveAddress = slaveAddr; xfer.subaddress = base_addr; xfer.subaddressSize = addrSize; custom->rx_sucess = false; /* request a read from SoC I2C controller */ if(I2C_MasterTransferNonBlocking(dat->I2C, &custom->mhandle, &xfer) != kStatus_Success) { ret = kDeviceIoError; } else { /* transfer started, wait response from hardware */ ret = uLipeDeviceStartSync(dev, timeout); if(ret == kStatusOk) { if(!custom->rx_sucess) { /* get how much data was arrived */ I2C_MasterTransferAbort(dat->I2C, &custom->mhandle); ret = kDeviceIoError; } else { *actualLen = expectedLen; } } else { I2C_MasterTransferGetCount(dat->I2C, &custom->mhandle, actualLen); I2C_MasterTransferAbort(dat->I2C, &custom->mhandle); ret = kTimeout; } } } else { /* todo, implement the slave driver */ ret = kNotImplementedForThisDevice; } custom->busy = false; cleanup: return(ret); }
static OsStatus_t KL25Z_I2CSendByte(Device_t *dev, uint16_t slaveAddr, uint32_t addr, uint8_t addrSize, uint8_t c, uint16_t timeout) { OsStatus_t ret = kStatusOk; KL25ZI2CDevData_t *dat = (KL25ZI2CDevData_t *)dev->config->devConfigData; KL25ZCustomI2CData_t *custom = (KL25ZCustomI2CData_t *)dev->deviceData; if(custom->busy) { /* device busy, exit */ ret = kDeviceBusy; goto cleanup; } if(!custom->enabled) { /* device already enabled, discard */ ret = kDeviceDisabled; goto cleanup; } /* lock device */ custom->busy = true; if(custom->master) { i2c_master_transfer_t xfer; xfer.data = &c; xfer.dataSize = sizeof(uint8_t); xfer.direction = kI2C_Write; xfer.slaveAddress = slaveAddr; xfer.subaddress = addr; xfer.subaddressSize = addrSize; custom->tx_sucess = false; /* request a write from SoC I2C controller */ /* request a write from SoC I2C controller */ if(I2C_MasterTransferNonBlocking(dat->I2C, &custom->mhandle, &xfer) != kStatus_Success) { ret = kDeviceIoError; } else { /* transfer started, wait response from hardware */ ret = uLipeDeviceStartSync(dev, timeout); if(ret == kStatusOk) { if(!custom->rx_sucess) { /* get how much data was arrived */ I2C_MasterTransferAbort(dat->I2C, &custom->mhandle); ret = kDeviceIoError; } } else { I2C_MasterTransferAbort(dat->I2C, &custom->mhandle); ret = kTimeout; } } } else { /* todo, implement the slave driver */ ret = kNotImplementedForThisDevice; } custom->busy = false; cleanup: return(ret); }