static int clock_byte_in(void)
{
	int i, b, ack;

	b = 0;
	make_sda_input();
	for (i = 0; i < 8; i++) {
		udelay(3);
		b = (b << 1) |  get_sda();
		udelay(3);
		set_scl(1);
		udelay(5);
		set_scl(0);
	}
	/* ack bit */
	udelay(5);
	set_scl(1);
	udelay(2);
	ack = get_sda();
	udelay(3);
	set_scl(0);
	make_scl_sda_outputs();

	return b;
}
Example #2
0
/*
 * I2C is a synchronous protocol and resets of the processor in the middle
 * of an access can block the I2C Bus until a powerdown of the full unit is
 * done. This function toggles the SCL until the SCL and SCA line are
 * released, but max. 16 times, after this a I2C start-sequence is sent.
 * This I2C Deblocking mechanism was developed by Keymile in association
 * with Anatech and Atmel in 1998.
 */
int i2c_make_abort(void)
{

#if defined(CONFIG_HARD_I2C) && !defined(MACH_TYPE_KM_KIRKWOOD)
	immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
	i2c8260_t *i2c	= (i2c8260_t *)&immap->im_i2c;

	/*
	 * disable I2C controller first, otherwhise it thinks we want to
	 * talk to the slave port...
	 */
	clrbits_8(&i2c->i2c_i2mod, 0x01);

	/* Set the PortPins to GPIO */
	setports(1);
#endif

	int	scl_state = 0;
	int	sda_state = 0;
	int	i = 0;
	int	ret = 0;

	if (!get_sda()) {
		ret = -1;
		while (i < 16) {
			i++;
			set_scl(0);
			udelay(DELAY_ABORT_SEQ);
			set_scl(1);
			udelay(DELAY_ABORT_SEQ);
			scl_state = get_scl();
			sda_state = get_sda();
			if (scl_state && sda_state) {
				ret = 0;
				printf("[INFO] i2c abort after %d clocks\n", i);
				break;
			}
		}
	}
	if (ret == 0)
		for (i = 0; i < 5; i++)
			i2c_write_start_seq();
	else
		printf("[ERROR] i2c abort failed\n");

	/* respect stop setup time */
	udelay(DELAY_ABORT_SEQ);
	set_scl(1);
	udelay(DELAY_ABORT_SEQ);
	set_sda(1);
	get_sda();

#if defined(CONFIG_HARD_I2C)
	/* Set the PortPins back to use for I2C */
	setports(0);
#endif
	return ret;
}
static void clock_byte_out(int b, int set_output)
{
	int i, ack;

	for (i = 0; i < 8; i++) {
		udelay(3);
		set_sda(b & 0x80);
		udelay(3);
		set_scl(1);
		udelay(5);	/* Tlow == 4.7 uS */
		set_scl(0);
		b <<= 1;
	}
	/* ack bit */
	make_sda_input();
	udelay(5);
	set_scl(1);
	udelay(2);
	ack = get_sda();
	udelay(3);
	set_scl(0);

	if (set_output) {
		make_scl_sda_outputs();
	}
}
Example #4
0
/** \brief Read a Byte in blocking mode and set the status.
 *
 * \param dev_num bsp_dev_i2c_t: I2C dev num.
 * \param rx_data uint8_t*: The received byte.
 * \return bsp_status_t: status of the transfer.
 *
 */
bsp_status_t bsp_i2c_master_read_u8(bsp_dev_i2c_t dev_num, uint8_t* rx_data)
{
	(void)dev_num;
	unsigned char data;
	int i;

	/* Read 8 bits */
	data = 0;
	for(i = 0; i < 8; i++) {
		set_sda_float();
		i2c_sw_delay();

		set_scl_float();
		i2c_sw_delay();

		data <<= 1;
		if(get_sda())
			data |= 1;

		set_scl_low();
		i2c_sw_delay();
	}
	*rx_data = data;

	/* Do not Send ACK / NACK because sent by bsp_i2c_read_ack() */

	return BSP_OK;
}
Example #5
0
/*
 * I2C is a synchronous protocol and resets of the processor in the middle
 * of an access can block the I2C Bus until a powerdown of the full unit is
 * done. This function toggles the SCL until the SCL and SCA line are
 * released, but max. 16 times, after this a I2C start-sequence is sent.
 * This I2C Deblocking mechanism was developed by Keymile in association
 * with Anatech and Atmel in 1998.
 */
int i2c_make_abort(void)
{
	int	scl_state = 0;
	int	sda_state = 0;
	int	i = 0;
	int	ret = 0;

	if (!get_sda()) {
		ret = -1;
		while (i < 16) {
			i++;
			set_scl(0);
			udelay(DELAY_ABORT_SEQ);
			set_scl(1);
			udelay(DELAY_ABORT_SEQ);
			scl_state = get_scl();
			sda_state = get_sda();
			if (scl_state && sda_state) {
				ret = 0;
				break;
			}
		}
	}
	if (ret == 0)
		for (i = 0; i < 5; i++)
			i2c_write_start_seq();

	/* respect stop setup time */
	udelay(DELAY_ABORT_SEQ);
	set_scl(1);
	udelay(DELAY_ABORT_SEQ);
	set_sda(1);
	get_sda();

	return ret;
}
Example #6
0
/** \brief Sends a Byte in blocking mode and set the status.
 *
 * \param dev_num bsp_dev_i2c_t: I2C dev num.
 * \param tx_data uint8_t: data to send.
 * \param tx_ack_flag bool*: TRUE means ACK, FALSE means NACK.
 * \return bsp_status_t: status of the transfer.
 *
 */
bsp_status_t bsp_i2c_master_write_u8(bsp_dev_i2c_t dev_num, uint8_t tx_data, bool* tx_ack_flag)
{
	(void)dev_num;
	int i;
	unsigned char ack_val;

	/* Write 8 bits */
	for(i = 0; i < 8; i++) {
		if(tx_data & 0x80)
			set_sda_float();
		else
			set_sda_low();

		i2c_sw_delay();

		set_scl_float();
		i2c_sw_delay();

		set_scl_low();
		tx_data <<= 1;
	}

	/* Read 1 bit ACK or NACK */
	set_sda_float();
	i2c_sw_delay();

	set_scl_float();
	i2c_sw_delay();

	ack_val = get_sda();

	set_scl_low();
	i2c_sw_delay();

	if(ack_val == 0)
		*tx_ack_flag = TRUE;
	else
		*tx_ack_flag = FALSE;

	return BSP_OK;
}
Example #7
0
int mi2c_put_byte(struct fd_dev *fd, int data)
{
	int i;
	int ack;

	for (i = 0; i < 8; i++, data<<=1) {
		set_sda(fd, data & 0x80);
		set_scl(fd, 1);
		set_scl(fd, 0);
	}

	set_sda(fd, 1);
	set_scl(fd, 1);

	ack = get_sda(fd);

	set_scl(fd, 0);
	set_sda(fd, 0);

	return ack ? -EIO : 0; /* ack low == success */
}
Example #8
0
static int mi2c_put_byte(struct fmc_device *fmc, int data)
{
	int i;
	int ack;

	for (i = 0; i < 8; i++, data<<=1) {
		set_sda(fmc, data & 0x80);
		set_scl(fmc, 1);
		set_scl(fmc, 0);
	}

	set_sda(fmc, 1);
	set_scl(fmc, 1);

	ack = get_sda(fmc);

	set_scl(fmc, 0);
	set_sda(fmc, 0);

	return ack ? -EIO : 0; /* ack low == success */
}
Example #9
0
int mi2c_get_byte(struct fd_dev *fd, unsigned char *data, int sendack)
{
	int i;
	int indata = 0;

	/* assert: scl is low */
	set_scl(fd, 0);
	set_sda(fd, 1);
	for (i = 0; i < 8; i++) {
		set_scl(fd, 1);
		indata <<= 1;
		if (get_sda(fd))
			indata |= 0x01;
		set_scl(fd, 0);
	}

	set_sda(fd, (sendack ? 0 : 1));
	set_scl(fd, 1);
	set_scl(fd, 0);
	set_sda(fd, 0);

	*data= indata;
	return 0;
}
Example #10
0
static int mi2c_get_byte(struct fmc_device *fmc, unsigned char *data, int ack)
{
	int i;
	int indata = 0;

	/* assert: scl is low */
	set_scl(fmc, 0);
	set_sda(fmc, 1);
	for (i = 0; i < 8; i++) {
		set_scl(fmc, 1);
		indata <<= 1;
		if (get_sda(fmc))
			indata |= 0x01;
		set_scl(fmc, 0);
	}

	set_sda(fmc, (ack ? 0 : 1));
	set_scl(fmc, 1);
	set_scl(fmc, 0);
	set_sda(fmc, 0);

	*data= indata;
	return 0;
}