コード例 #1
0
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;
}
コード例 #2
0
static int cs43l42_i2c_read(int addr, int reg)
{
	int b;

	/*
	 * start of frame
	 */
	set_sda(1);
	set_scl(1);
	udelay(5);	/* Tbuf == 4.7 uS */
	set_sda(0);
	udelay(4);	/* Thdst == 4 uS */
	set_scl(0);
	clock_byte_out(addr | 0x01, 1);
	clock_byte_out(reg, 0);
	b = clock_byte_in();
	/*
	 * end of frame
	 */
	set_sda(1);
	set_scl(1);
	udelay(5);

	return b;
}
コード例 #3
0
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();
	}
}
コード例 #4
0
ファイル: Wire.cpp プロジェクト: ADTL/libmaple
void TwoWire::i2c_shift_out(uint8 val) {
    int i;
    for (i = 0; i < 8; i++) {
        set_sda(!!(val & (1 << (7 - i)) ) );
        set_scl(HIGH);
        set_scl(LOW);
    }
}
コード例 #5
0
ファイル: common.c プロジェクト: Biamp-Systems/blackfin-uboot
/*
 * 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;
}
コード例 #6
0
ファイル: Wire.cpp プロジェクト: ADTL/libmaple
bool TwoWire::i2c_get_ack() {
    set_scl(LOW);
    set_sda(HIGH);
    set_scl(HIGH);

    bool ret = !digitalRead(this->sda_pin);
    set_scl(LOW);
    return ret;
}
コード例 #7
0
ファイル: common.c プロジェクト: Biamp-Systems/blackfin-uboot
static void i2c_write_start_seq(void)
{
	set_sda(1);
	udelay(DELAY_HALF_PERIOD);
	set_scl(1);
	udelay(DELAY_HALF_PERIOD);
	set_sda(0);
	udelay(DELAY_HALF_PERIOD);
	set_scl(0);
	udelay(DELAY_HALF_PERIOD);
}
コード例 #8
0
ファイル: Wire.cpp プロジェクト: ADTL/libmaple
uint8 TwoWire::i2c_shift_in() {
    uint8 data = 0;
    set_sda(HIGH);

    int i;
    for (i = 0; i < 8; i++) {
        set_scl(HIGH);
        data |= digitalRead(this->sda_pin) << (7-i);
        set_scl(LOW);
    }

    return data;
}
コード例 #9
0
irom i2c_error_t i2c_reset(void)
{
	int current;

	if(!i2c_flags.init_done)
		return(i2c_error_no_init);

	state = i2c_state_stop_send;

	send_stop();

	// if someone is holding the sda line, simulate clock cycles
	// to make them release it

	for(current = i2c_config_idle_timeout; current > 0; current--)
	{
		if(sda_is_set())
			break;

		clear_scl();
		delay();
		set_scl();
		delay();
	}

	if(!sda_is_set())
		return(i2c_error_sda_stuck);

	if(!scl_is_set())
		return(i2c_error_bus_lock);

	state = i2c_state_idle;

	return(i2c_error_ok);
}
コード例 #10
0
irom static i2c_error_t receive_bit(bool_t *bit)
{
	int current, total;
	i2c_error_t error;

	// at this point scl should be high and sda is unknown,
	// but should be high before reading
	
	if(state == i2c_state_idle)
		return(i2c_error_invalid_state_idle);

	// wait for scl to be released by slave (clock stretching)
	
	if((error = wait_idle()) != i2c_error_ok)
		return(error);
	
	// make sure sda is high (open) so slave can pull it
	// do it while clock is pulled
	
	clear_scl();
	set_sda();

	// wait for slave to pull/release sda

	delay();

	// release clock again

	set_scl();

	// take care of clock stretching

	if((error = wait_idle()) != i2c_error_ok)
		return(error);

	delay();

	// do oversampling of sda, to implement a software
	// low-pass filter / spike filter

	for(total = 0, current = 0; current < i2c_config_sda_sampling_window; current++)
	{
		int set;
		set = sda_is_set();

		total += set ? 4 : 0;

		short_delay();
	}

	if(total < (i2c_config_sda_sampling_window * 1))		// 0-1/4	=> 0
		*bit = 0;
	else if(total < (i2c_config_sda_sampling_window * 3))	// 1/4-3/4	=> error
		return(i2c_error_receive_error);
	else													// 3/4-1	=> 1
		*bit = 1;

	return(i2c_error_ok);
}
コード例 #11
0
static int cs43l42_i2c_write(int addr, int reg, int value)
{
	set_sda(1);
	set_scl(1);
	udelay(5);
	set_sda(0);
	udelay(4);
	set_scl(0);
	clock_byte_out(addr, 1);
	clock_byte_out(reg, 1);
	clock_byte_out(value, 1);
	set_sda(1);
	set_scl(1);
	udelay(5);

	return 0;
}
コード例 #12
0
ファイル: Wire.cpp プロジェクト: ADTL/libmaple
void TwoWire::begin(uint8 self_addr) {
    tx_buf_idx = 0;
    tx_buf_overflow = false;
    rx_buf_idx = 0;
    rx_buf_len = 0;
    pinMode(this->scl_pin, OUTPUT_OPEN_DRAIN);
    pinMode(this->sda_pin, OUTPUT_OPEN_DRAIN);
    set_scl(HIGH);
    set_sda(HIGH);
}
コード例 #13
0
ファイル: goramo_mlr.c プロジェクト: 0x0f/adam-kernel
static void output_control(void)
{
	int i;

	gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
	gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);

	for (i = 0; i < 8; i++) {
		set_scl(0);
		set_sda(control_value & (0x80 >> i)); /* MSB first */
		set_scl(1);	/* active edge */
	}

	set_str(1);
	set_str(0);

	set_scl(0);
	set_sda(1);		/* Be ready for START */
	set_scl(1);
}
コード例 #14
0
static void output_control(void)
{
	int i;

	gpio_line_config(GPIO_SCL, IXP4XX_GPIO_OUT);
	gpio_line_config(GPIO_SDA, IXP4XX_GPIO_OUT);

	for (i = 0; i < 8; i++) {
		set_scl(0);
		set_sda(control_value & (0x80 >> i)); /*           */
		set_scl(1);	/*             */
	}

	set_str(1);
	set_str(0);

	set_scl(0);
	set_sda(1);		/*                    */
	set_scl(1);
}
コード例 #15
0
ファイル: i2c.c プロジェクト: aewallin/fine-delay-sw
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 */
}
コード例 #16
0
ファイル: spec-i2c.c プロジェクト: dcobas/svec
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 */
}
コード例 #17
0
irom static i2c_error_t send_start(void)
{
	i2c_error_t error;
	int current;

	if(state != i2c_state_start_send)
		return(i2c_error_invalid_state_not_send_start);

	// wait for scl and sda to be released by all masters and slaves
	
	state = i2c_state_bus_wait_1;

	if((error = wait_idle()) != i2c_error_ok)
		return(error);

	// set sda to high

	clear_scl();
	delay();

	if(scl_is_set())
		return(i2c_error_bus_lock);

	set_sda();
	delay();

	if(!sda_is_set())
		return(i2c_error_sda_stuck);

	set_scl();
	delay();

	state = i2c_state_bus_wait_2;

	// demand bus is idle for a minimum window

	for(current = i2c_config_scl_sampling_window; current > 0; current--)
	{
		if(!scl_is_set() || !sda_is_set())
			return(i2c_error_bus_lock);
		short_delay();
	}

	// generate start condition by leaving scl high and pulling sda low

	clear_sda();
	delay();

	if(sda_is_set())
		return(i2c_error_sda_stuck);

	return(i2c_error_ok);
}
コード例 #18
0
irom static i2c_error_t send_stop(void)
{
	i2c_error_t error;

	if(state != i2c_state_stop_send)
		return(i2c_error_invalid_state_not_send_stop);

	// at this point scl should be high and sda is unknown
	// wait for scl to be released by all masters and slaves
	
	if((error = wait_idle()) != i2c_error_ok)
		return(error);

	delay();

	// set sda to low

	clear_scl();
	delay();

	if(scl_is_set())
		return(i2c_error_bus_lock);

	clear_sda();
	delay();

	if(sda_is_set())
		return(i2c_error_sda_stuck);

	set_scl();
	delay();

	if(sda_is_set())
		return(i2c_error_sda_stuck);

	if(!scl_is_set())
		return(i2c_error_bus_lock);

	// now generate the stop condition by leaving scl high and setting sda high

	set_sda();
	delay();

	if(!scl_is_set())
		return(i2c_error_bus_lock);

	if(!sda_is_set())
		return(i2c_error_sda_stuck);

	return(i2c_error_ok);
}
コード例 #19
0
ファイル: common.c プロジェクト: CogSystems/u-boot
/*
 * 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;
}
コード例 #20
0
ファイル: i2c.c プロジェクト: aewallin/fine-delay-sw
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;
}
コード例 #21
0
ファイル: spec-i2c.c プロジェクト: dcobas/svec
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;
}
コード例 #22
0
irom static i2c_error_t send_bit(bool_t bit)
{
	i2c_error_t error;

	// at this point scl should be high and sda will be unknown
	// wait for scl to be released by slave (clock stretching)
	
	if((error = wait_idle()) != i2c_error_ok)
		return(error);
	
	clear_scl();
	delay();

	if(scl_is_set())
		return(i2c_error_bus_lock);

	if(bit)
	{
		set_sda();
		delay();

		if(!sda_is_set())
			return(i2c_error_sda_stuck);
	}
	else
	{
		clear_sda();
		delay();

		if(sda_is_set())
			return(i2c_error_sda_stuck);
	}

	set_scl();
	delay();

	// take care of clock stretching

	if((error = wait_idle()) != i2c_error_ok)
		return(error);

	return(i2c_error_ok);
}
コード例 #23
0
ファイル: i2c.c プロジェクト: aewallin/fine-delay-sw
static void mi2c_stop(struct fd_dev *fd)
{
	set_sda(fd, 0);
	set_scl(fd, 1);
	set_sda(fd, 1);
}
コード例 #24
0
ファイル: Wire.cpp プロジェクト: ADTL/libmaple
void TwoWire::i2c_send_nack() {
    set_sda(HIGH);
    set_scl(HIGH);
    set_scl(LOW);
}
コード例 #25
0
ファイル: Wire.cpp プロジェクト: ADTL/libmaple
void TwoWire::i2c_stop() {
    set_sda(LOW);
    set_scl(HIGH);
    set_sda(HIGH);
}
コード例 #26
0
ファイル: Wire.cpp プロジェクト: ADTL/libmaple
void TwoWire::i2c_start() {
    set_sda(LOW);
    set_scl(LOW);
}
コード例 #27
0
ファイル: spec-i2c.c プロジェクト: dcobas/svec
static void mi2c_stop(struct fmc_device *fmc)
{
	set_sda(fmc, 0);
	set_scl(fmc, 1);
	set_sda(fmc, 1);
}
コード例 #28
0
ファイル: spec-i2c.c プロジェクト: dcobas/svec
void mi2c_init(struct fmc_device *fmc)
{
	set_scl(fmc, 1);
	set_sda(fmc, 1);
}
コード例 #29
0
ファイル: i2c.c プロジェクト: aewallin/fine-delay-sw
void mi2c_init(struct fd_dev *fd)
{
	set_scl(fd, 1);
	set_sda(fd, 1);
}