예제 #1
0
static void i2c_lpc2_putc(I2c *i2c, uint8_t data)
{
	HWREG(i2c->hw->base + I2C_DAT_OFF) = data;
	HWREG(i2c->hw->base + I2C_CONCLR_OFF) = BV(I2CON_SIC);

	WAIT_SI(i2c);

	uint32_t status = HWREG(i2c->hw->base + I2C_STAT_OFF);


	/* Generate the stop if we finish to send all programmed bytes */
	if (i2c->xfer_size == 1)
	{
		if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
			i2c_hw_stop(i2c);
	}

	if (status == I2C_STAT_DATA_NACK)
	{
		LOG_ERR("Data NACK\n");
		i2c->errors |= I2C_NO_ACK;
		i2c_hw_stop(i2c);
	}
	else if ((status == I2C_STAT_ERROR) || (status == I2C_STAT_UNKNOW))
	{
		LOG_ERR("I2C error.\n");
		i2c->errors |= I2C_ERR;
		i2c_hw_stop(i2c);
	}
}
예제 #2
0
static uint8_t i2c_lpc2_getc(I2c *i2c)
{
	/*
	 * Set ack bit if we want read more byte, otherwise
	 * we disable it
	 */
	if (i2c->xfer_size > 1)
		HWREG(i2c->hw->base + I2C_CONSET_OFF) = BV(I2CON_AA);
	else
		HWREG(i2c->hw->base + I2C_CONCLR_OFF) = BV(I2CON_AAC);

	HWREG(i2c->hw->base + I2C_CONCLR_OFF) = BV(I2CON_SIC);

	WAIT_SI(i2c);

	uint32_t status = HWREG(i2c->hw->base + I2C_STAT_OFF);
	uint8_t data = (uint8_t)HWREG(i2c->hw->base + I2C_DAT_OFF);

	if (status == I2C_STAT_RDATA_ACK)
	{
		return data;
	}
	else if (status == I2C_STAT_RDATA_NACK)
	{
		/*
		 * last byte to read generate the stop if
		 * required
		 */
		if (I2C_TEST_STOP(i2c->flags) == I2C_STOP)
			i2c_hw_stop(i2c);

		return data;
	}
	else if ((status == I2C_STAT_ERROR) || (status == I2C_STAT_UNKNOW))
	{
		LOG_ERR("I2C error.\n");
		i2c->errors |= I2C_ERR;
		i2c_hw_stop(i2c);
	}

	return 0xFF;
}
예제 #3
0
static void i2c_lpc2_start(struct I2c *i2c, uint16_t slave_addr)
{
	if (I2C_TEST_START(i2c->flags) == I2C_START_W)
	{
		ticks_t start = timer_clock();
		while (true)
		{
			i2c_hw_restart(i2c);

			uint8_t status = HWREG(i2c->hw->base + I2C_STAT_OFF);

			/* Start status ok, set addres and the R/W bit */
			if ((status == I2C_STAT_SEND) || (status == I2C_STAT_RESEND))
				HWREG(i2c->hw->base + I2C_DAT_OFF) = slave_addr & ~I2C_READBIT;

			/* Clear the start bit and clear the SI bit */
			HWREG(i2c->hw->base + I2C_CONCLR_OFF) = BV(I2CON_SIC) | BV(I2CON_STAC);

			if (status == I2C_STAT_SLAW_ACK)
				break;

			if (status == I2C_STAT_ARB_LOST)
			{
				LOG_ERR("Arbitration lost\n");
				i2c->errors |= I2C_ARB_LOST;
				i2c_hw_stop(i2c);
			}

			if (timer_clock() - start > ms_to_ticks(CONFIG_I2C_START_TIMEOUT))
			{
				LOG_ERR("Timeout on I2C START\n");
				i2c->errors |= I2C_NO_ACK;
				i2c_hw_stop(i2c);
				break;
			}
		}
	}
	else if (I2C_TEST_START(i2c->flags) == I2C_START_R)
	{
		i2c_hw_restart(i2c);

		uint8_t status = HWREG(i2c->hw->base + I2C_STAT_OFF);

		/* Start status ok, set addres and the R/W bit */
		if ((status == I2C_STAT_SEND) || (status == I2C_STAT_RESEND))
			HWREG(i2c->hw->base + I2C_DAT_OFF) = slave_addr | I2C_READBIT;

		/* Clear the start bit and clear the SI bit */
		HWREG(i2c->hw->base + I2C_CONCLR_OFF) = BV(I2CON_SIC) | BV(I2CON_STAC);

		WAIT_SI(i2c);

		status = HWREG(i2c->hw->base + I2C_STAT_OFF);

		if (status == I2C_STAT_SLAR_NACK)
		{
			LOG_ERR("SLAR NACK:%02x\n", status);
			i2c->errors |= I2C_NO_ACK;
			i2c_hw_stop(i2c);
		}

		if (status == I2C_STAT_ARB_LOST)
		{
			LOG_ERR("Arbitration lost\n");
			i2c->errors |= I2C_ARB_LOST;
			i2c_hw_stop(i2c);
		}
	}
	else
	{
		ASSERT(0);
	}
}
예제 #4
0
파일: i2cget.c 프로젝트: derf/vusb-i2c
int main(int argc, char **argv)
{
	int i, address, cmdbuf;
	int num_bytes = 1;
	unsigned int ret;
	char *conv_err;

	i2c_getopt(argc, argv);

	if (argc < 3) {
		fputs("Usage: vusb-i2cget <address> <num_bytes> [register ...] ", stderr);
		return 1;
	}

	address = strtol(argv[1], &conv_err, 0);

	if (conv_err && *conv_err) {
		fprintf(stderr, "address: Conversion error at '%s'\n", conv_err);
		return 2;
	}

	num_bytes = strtol(argv[2], &conv_err, 0);

	if (conv_err && *conv_err) {
		fprintf(stderr, "num_bytes: Conversion error at '%s'\n", conv_err);
		return 2;
	}

	i2c_init();

	if (argc >= 3) {
		i2c_hw_start();

		if (!i2c_hw_tx_byte((address << 1) | 0)) {
			fprintf(stderr, "Received NAK from slave 0x%02x, aborting\n", address);
			i2c_hw_stop();
			i2c_deinit();
			return 3;
		}
	}

	for (i = 3; i < argc; i++) {
		cmdbuf = strtol(argv[i], &conv_err, 0);
		if (conv_err && *conv_err) {
			fprintf(stderr, "read command: Conversion error at '%s'\n", conv_err);
			i2c_hw_stop();
			i2c_deinit();
			return 2;
		}
		if (!i2c_hw_tx_byte(cmdbuf)) {
			fprintf(stderr, "Received NAK after byte %d (0x%02x)\n", i-1, cmdbuf);
			i2c_hw_stop();
			i2c_deinit();
			return 4;
		}
	}

	i2c_hw_start();
	if (!i2c_hw_tx_byte((address << 1) | 1)) {
		fprintf(stderr, "Received NAK after reSTART from slave 0x%02x, aborting\n", address);
		i2c_hw_stop();
		i2c_deinit();
		return 3;
	}

	for (i = 1; i <= num_bytes; i++) {
		printf("%i ", i2c_hw_rx_byte((i < num_bytes) * 1));
	}
	putc('\n', stdout);

	i2c_hw_stop();
	i2c_deinit();

	return 0;
}