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; }
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; }
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(); } }
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); } }
/* * 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; }
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; }
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); }
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; }
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); }
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); }
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; }
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); }
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); }
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); }
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 */ }
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 */ }
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); }
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); }
/* * 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; }
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; }
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; }
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); }
static void mi2c_stop(struct fd_dev *fd) { set_sda(fd, 0); set_scl(fd, 1); set_sda(fd, 1); }
void TwoWire::i2c_send_nack() { set_sda(HIGH); set_scl(HIGH); set_scl(LOW); }
void TwoWire::i2c_stop() { set_sda(LOW); set_scl(HIGH); set_sda(HIGH); }
void TwoWire::i2c_start() { set_sda(LOW); set_scl(LOW); }
static void mi2c_stop(struct fmc_device *fmc) { set_sda(fmc, 0); set_scl(fmc, 1); set_sda(fmc, 1); }
void mi2c_init(struct fmc_device *fmc) { set_scl(fmc, 1); set_sda(fmc, 1); }
void mi2c_init(struct fd_dev *fd) { set_scl(fd, 1); set_sda(fd, 1); }