Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
0
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);
}