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; }
/* * 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(); } }
/** \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; }
/* * 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; }
/** \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; }
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 */ }
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; }