float ds1721_read() { unsigned char hi, lo; unsigned char i; short tmp = 1; float rev; float frac[] = { 0.0625, 0.125, 0.25, 0.5 }; i2c_send_start(); i2c_send_byte(DS1721_ADDR | DS1721_WRITE); i2c_send_byte(DS1721_CMD_READ); i2c_send_start(); /* restart */ i2c_send_byte(DS1721_ADDR | DS1721_READ); hi = i2c_read_byte(1); lo = i2c_read_byte(1); // _delay_us(70); /* WHAT ?! */ // i2c_send_stop(); // task_sm.piezo0_count = 5; //////////////// //////////////// if (hi & 0x80) { /* negative */ tmp = (hi << 8) + lo; tmp = ~tmp; tmp++; hi = tmp >> 8; lo = tmp & 0x00ff; tmp = -1; }
uint8_t i2c_read_byte(uint8_t dev, uint8_t addr){ if(i2c_send_start()!=0) return 0; if(i2c_send_addr(dev,TW_WRITE)!=0) return 0; if(i2c_send_data(addr)!=0) return 0; if(i2c_send_start()!=0) return 0; if(i2c_send_addr(dev,TW_READ)!=0) return 0; uint8_t data= i2c_receive_data(0); i2c_send_stop(); return data; }
void i2c_seq_read(uint8_t dev, uint8_t start_addr, uint8_t*buff, uint8_t len){ int i=0; if(i2c_send_start()!=0) return; if(i2c_send_addr(dev,TW_WRITE)!=0) return; if(i2c_send_data(start_addr)!=0) return; if(i2c_send_start()!=0) return; if(i2c_send_addr(dev,TW_READ)!=0) return; for(i=0;i<len;i++) *buff++=i2c_receive_data((i<(len-1))?1:0); //send ack until last byte to read i2c_send_stop(); }
int16_t i2c_read_word(uint8_t dev, uint8_t addr){ if(i2c_send_start()!=0) return 0; if(i2c_send_addr(dev,TW_WRITE)!=0) return 0; if(i2c_send_data(addr)!=0) return 0; if(i2c_send_start()!=0) return 0; if(i2c_send_addr(dev,TW_READ)!=0) return 0; uint8_t datal= i2c_receive_data(1); uint8_t datah= i2c_receive_data(0); i2c_send_stop(); return ((datah<<8) | datal); }
static uint32_t i2c_read(uint8_t reg) { // while ((I2C_SR2(i2c) & I2C_SR2_BUSY)) { // } i2c_send_start(I2C_PORT); /* Wait for master mode selected */ while (!((I2C_SR1(I2C_PORT) & I2C_SR1_SB) & (I2C_SR2(I2C_PORT) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); i2c_send_7bit_address(I2C_PORT, SLAVE_ADDRESS, I2C_WRITE); /* Waiting for address is transferred. */ while (!(I2C_SR1(I2C_PORT) & I2C_SR1_ADDR)); /* Cleaning ADDR condition sequence. */ uint32_t reg32 = I2C_SR2(I2C_PORT); (void) reg32; /* unused */ /* Common stuff ABOVE HERE */ i2c_send_data(I2C_PORT, reg); while (!(I2C_SR1(I2C_PORT) & (I2C_SR1_BTF))); i2c_send_start(I2C_PORT); /* Wait for master mode selected */ while (!((I2C_SR1(I2C_PORT) & I2C_SR1_SB) & (I2C_SR2(I2C_PORT) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); i2c_send_7bit_address(I2C_PORT, SLAVE_ADDRESS, I2C_READ); /* Waiting for address is transferred. */ while (!(I2C_SR1(I2C_PORT) & I2C_SR1_ADDR)); i2c_disable_ack(I2C_PORT); /* Cleaning ADDR condition sequence. */ reg32 = I2C_SR2(I2C_PORT); (void) reg32; /* unused */ i2c_send_stop(I2C_PORT); while (!(I2C_SR1(I2C_PORT) & I2C_SR1_RxNE)); uint32_t result = i2c_get_data(I2C_PORT); i2c_enable_ack(I2C_PORT); I2C_SR1(I2C_PORT) &= ~I2C_SR1_AF; return result; }
int tda18219_read_reg(uint8_t reg, uint8_t* value) { uint32_t __attribute__((unused)) reg32; /* Send START condition. */ i2c_send_start(I2C1); /* Waiting for START is send and switched to master mode. */ while (!((I2C_SR1(I2C1) & I2C_SR1_SB) & (I2C_SR2(I2C1) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); /* Say to what address we want to talk to. */ /* Yes, WRITE is correct - for selecting register in STTS75. */ i2c_send_7bit_address(I2C1, TDA18219_I2C_ADDR, I2C_WRITE); /* Waiting for address is transferred. */ while (!(I2C_SR1(I2C1) & I2C_SR1_ADDR)); /* Cleaning ADDR condition sequence. */ reg32 = I2C_SR2(I2C1); i2c_send_data(I2C1, reg); while (!(I2C_SR1(I2C1) & (I2C_SR1_BTF | I2C_SR1_TxE))); /* Send re-START condition. */ i2c_send_start(I2C1); /* Waiting for START is send and switched to master mode. */ while (!((I2C_SR1(I2C1) & I2C_SR1_SB) & (I2C_SR2(I2C1) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); /* Say to what address we want to talk to. */ i2c_send_7bit_address(I2C1, TDA18219_I2C_ADDR, I2C_READ); I2C_CR1(I2C1) &= ~I2C_CR1_ACK; /* Waiting for address is transferred. */ while (!(I2C_SR1(I2C1) & I2C_SR1_ADDR)); /* Cleaning ADDR condition sequence. */ reg32 = I2C_SR2(I2C1); i2c_send_stop(I2C1); while (!(I2C_SR1(I2C1) & I2C_SR1_RxNE)); *value = I2C_DR(I2C1); return 0; }
static int i2c_write(uint8_t reg, uint8_t val) { while ((I2C_SR2(I2C_PORT) & I2C_SR2_BUSY)) { } gpio_set(GPIOG, GPIO13); i2c_send_start(I2C_PORT); /* Wait for master mode selected */ while (!((I2C_SR1(I2C_PORT) & I2C_SR1_SB) & (I2C_SR2(I2C_PORT) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); gpio_set(GPIOG, GPIO14); i2c_send_7bit_address(I2C_PORT, SLAVE_ADDRESS, I2C_WRITE); /* Waiting for address is transferred. */ while (!(I2C_SR1(I2C_PORT) & I2C_SR1_ADDR)); /* Cleaning ADDR condition sequence. */ uint32_t reg32 = I2C_SR2(I2C_PORT); (void) reg32; /* unused */ /* Common above here */ /* Sending the data. */ i2c_send_data(I2C_PORT, reg); while (!(I2C_SR1(I2C_PORT) & (I2C_SR1_BTF))); i2c_send_data(I2C_PORT, val); while (!(I2C_SR1(I2C_PORT) & (I2C_SR1_BTF | I2C_SR1_TxE))); /* Send STOP condition. */ i2c_send_stop(I2C_PORT); return 0; }
static inline void PPRZ_I2C_SEND_START(struct i2c_periph *periph) { uint32_t i2c = (uint32_t) periph->reg_addr; // Reset the buffer pointer to the first byte periph->idx_buf = 0; #ifdef I2C_DEBUG_LED LED_SHOW_ACTIVE_BITS(regs); LED2_ON(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED1_ON(); LED1_OFF(); LED2_OFF(); #endif // Enable Error IRQ, Event IRQ but disable Buffer IRQ i2c_enable_interrupt(i2c, I2C_CR2_ITERREN); i2c_enable_interrupt(i2c, I2C_CR2_ITEVTEN); i2c_disable_interrupt(i2c, I2C_CR2_ITBUFEN); // Issue a new start i2c_nack_current(i2c); i2c_disable_ack(i2c); i2c_clear_stop(i2c); i2c_peripheral_enable(i2c); i2c_send_start(i2c); periph->status = I2CStartRequested; }
void stts75_write_config(uint32_t i2c, uint8_t sensor) { uint32_t reg32 __attribute__((unused)); /* Send START condition. */ i2c_send_start(i2c); /* Waiting for START is send and switched to master mode. */ while (!((I2C_SR1(i2c) & I2C_SR1_SB) & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); /* Send destination address. */ i2c_send_7bit_address(i2c, sensor, I2C_WRITE); /* Waiting for address is transferred. */ while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); /* Cleaning ADDR condition sequence. */ reg32 = I2C_SR2(i2c); /* Sending the data. */ i2c_send_data(i2c, 0x1); /* stts75 config register */ while (!(I2C_SR1(i2c) & I2C_SR1_BTF)); /* Await ByteTransferedFlag. */ /* Polarity reverse - LED glows if temp is below Tos/Thyst. */ i2c_send_data(i2c, 0x4); while (!(I2C_SR1(i2c) & (I2C_SR1_BTF | I2C_SR1_TxE))); /* Send STOP condition. */ i2c_send_stop(i2c); }
void stts75_write_temp_os(uint32_t i2c, uint8_t sensor, uint16_t temp_os) { uint32_t reg32 __attribute__((unused)); /* Send START condition. */ i2c_send_start(i2c); /* Waiting for START is send and switched to master mode. */ while (!((I2C_SR1(i2c) & I2C_SR1_SB) & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); /* Send destination address. */ i2c_send_7bit_address(i2c, sensor, I2C_WRITE); /* Waiting for address is transferred. */ while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); /* Cleaning ADDR condition sequence. */ reg32 = I2C_SR2(i2c); /* Sending the data. */ i2c_send_data(i2c, 0x3); /* OvertemperatureShutdown register */ while (!(I2C_SR1(i2c) & I2C_SR1_BTF)); i2c_send_data(i2c, (uint8_t)(temp_os >> 8)); /* MSB */ while (!(I2C_SR1(i2c) & I2C_SR1_BTF)); i2c_send_data(i2c, (uint8_t)(temp_os & 0xff00)); /* LSB */ /* After the last byte we have to wait for TxE too. */ while (!(I2C_SR1(i2c) & (I2C_SR1_BTF | I2C_SR1_TxE))); /* Send STOP condition. */ i2c_send_stop(i2c); }
int i2c_read (uint8_t chip_id, uint8_t reg_addr, uint8_t* buffer, uint16_t len) { int status = 0; /* send chip internal register address (pointer register) */ if (status == 0) i2c_send_start (); if (status == 0) status = i2c_write_byte (chip_id << 1 | I2C_WRITE_OPER); if (status == 0) status = i2c_write_byte (reg_addr); if (status == 0) i2c_send_repeated_start (); /* send again chip id before to switch to read mode */ if (status == 0) status = i2c_write_byte ((chip_id << 1) | I2C_READ_OPER); if (status == 0) i2c_switch_to_read_operation(len > 1); /* read specified number of bytes */ if (status == 0) { while (len > 1) { *buffer++ = i2c_read_byte (--len > 1); } } i2c_send_stop (); if (status == 0) *buffer++ = i2c_read_byte (false); return status; }
/* Function to write a byte at a specific address */ bool eeprom_write_byte(uint16_t address, uint8_t data) { bool success = true; /* send START and wait for completion */ i2c_send_start(I2C1); while ((I2C_SR1(I2C1) & I2C_SR1_SB) == 0); /* send device address, r/w request and wait for completion */ i2c_send_7bit_address(I2C1, ADDRESS_BYTE, I2C_WRITE); while ((I2C_SR1(I2C1) & I2C_SR1_ADDR) == 0); /* check SR2 and go on if OK */ if ((I2C_SR2(I2C1) & I2C_SR2_MSL) /* master mode */ && (I2C_SR2(I2C1) & I2C_SR2_BUSY)) { /* communication ongoing */ /* send memory address MSB */ i2c_send_data(I2C1, ((uint8_t)(address >> 8))); while ((I2C_SR1(I2C1) & I2C_SR1_TxE) == 0); /* send memory address LSB */ i2c_send_data(I2C1, ((uint8_t)address)); while ((I2C_SR1(I2C1) & I2C_SR1_TxE) == 0); /* send data byte */ i2c_send_data(I2C1, data); while ((I2C_SR1(I2C1) & I2C_SR1_TxE) == 0); /* send stop */ i2c_send_stop(I2C1); /* ATTENTION: consider to wait for a while */ } else {
/** \brief This function resynchronizes communication. * * Parameters are not used for I2C.\n * Re-synchronizing communication is done in a maximum of three steps * listed below. This function implements the first step. Since * steps 2 and 3 (sending a Wake-up token and reading the response) * are the same for I2C and SWI, they are * implemented in the communication layer (#ecc108c_resync). <ol> <li> To ensure an IO channel reset, the system should send the standard I2C software reset sequence, as follows: <ul> <li>a Start condition</li> <li>nine cycles of SCL, with SDA held high</li> <li>another Start condition</li> <li>a Stop condition</li> </ul> It should then be possible to send a read sequence and if synchronization has completed properly the ATECC108 will acknowledge the device address. The chip may return data or may leave the bus floating (which the system will interpret as a data value of 0xFF) during the data periods.\n If the chip does acknowledge the device address, the system should reset the internal address counter to force the ATECC108 to ignore any partial input command that may have been sent. This can be accomplished by sending a write sequence to word address 0x00 (Reset), followed by a Stop condition. </li> <li> If the chip does NOT respond to the device address with an ACK, then it may be asleep. In this case, the system should send a complete Wake token and wait t_whi after the rising edge. The system may then send another read sequence and if synchronization has completed the chip will acknowledge the device address. </li> <li> If the chip still does not respond to the device address with an acknowledge, then it may be busy executing a command. The system should wait the longest TEXEC and then send the read sequence, which will be acknowledged by the chip. </li> </ol> * \param[in] size size of rx buffer * \param[out] response pointer to response buffer * \return status of the operation */ uint8_t ecc108p_resync(uint8_t size, uint8_t *response) { uint8_t nine_clocks = 0xFF; uint8_t ret_code = i2c_send_start(); // Do not evaluate the return code that most likely indicates error, // since nine_clocks is unlikely to be acknowledged. (void) i2c_send_bytes(1, &nine_clocks); // Send another Start. The function sends also one byte, // the I2C address of the device, because I2C specification // does not allow sending a Stop right after a Start condition. ret_code = ecc108p_send_slave_address(I2C_READ); // Send only a Stop if the above call succeeded. // Otherwise the above function has sent it already. if (ret_code == I2C_FUNCTION_RETCODE_SUCCESS) ret_code = i2c_send_stop(); // Return error status if we failed to re-sync. if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS) return ECC108_COMM_FAIL; // Try to send a Reset IO command if re-sync succeeded. return ecc108p_reset_io(); }
void write_i2c(uint32_t i2c, uint8_t i2c_addr, uint8_t reg, uint8_t size, uint8_t *data) { int wait; int i; while (i2c_busy(i2c) == 1); while (i2c_is_start(i2c) == 1); /*Setting transfer properties*/ i2c_set_bytes_to_transfer(i2c, size + 1); i2c_set_7bit_address(i2c, (i2c_addr & 0x7F)); i2c_set_write_transfer_dir(i2c); i2c_enable_autoend(i2c); /*start transfer*/ i2c_send_start(i2c); wait = true; while (wait) { if (i2c_transmit_int_status(i2c)) { wait = false; } while (i2c_nack(i2c)); } i2c_send_data(i2c, reg); for (i = 0; i < size; i++) { wait = true; while (wait) { if (i2c_transmit_int_status(i2c)) { wait = false; } while (i2c_nack(i2c)); } i2c_send_data(i2c, data[i]); } }
float tmp_read_temperature(void) { // Store signed temperature info (12 bit from device, with 4LSBs = 0) s16 temperature; // Dummy variable to store read results from registers that must be read u32 reg; // Send START i2c_send_start(I2C1); while(!(I2C1_SR1 & I2C_SR1_SB)); // Send the TMP102's address and READ i2c_send_7bit_address(I2C1, 0x48, I2C_READ); while(!(I2C1_SR1 & I2C_SR1_ADDR)); // Clear ADDR bit, send ACKs, read byte one (MSB) reg = I2C1_SR2; I2C1_CR1 |= I2C_CR1_ACK; while(!(I2C1_SR1 & I2C_SR1_BTF)); temperature = (u16)(I2C1_DR << 8); // Stop sending ACKs, send STOP, read byte two (LSB) I2C1_CR1 &= ~I2C_CR1_ACK; I2C1_CR1 |= I2C_CR1_STOP; while(!(I2C1_SR1 & I2C_SR1_BTF)); temperature |= I2C1_DR; temperature >>= 4; return (float)temperature * 0.0625; }
void stts75_write_temp_hyst(uint32_t i2c, uint8_t sensor, uint16_t temp_hyst) { uint32_t reg32 __attribute__((unused)); /* Send START condition. */ i2c_send_start(i2c); /* Waiting for START is send and therefore switched to master mode. */ while (!((I2C_SR1(i2c) & I2C_SR1_SB) & (I2C_SR2(i2c) & (I2C_SR2_MSL | I2C_SR2_BUSY)))); /* Say to what address we want to talk to. */ i2c_send_7bit_address(i2c, sensor, I2C_WRITE); /* Waiting for address is transferred. */ while (!(I2C_SR1(i2c) & I2C_SR1_ADDR)); /* Cleaning ADDR condition sequence. */ reg32 = I2C_SR2(i2c); /* Sending the data. */ i2c_send_data(i2c, 0x2); /* TemperatureHysteresis register */ while (!(I2C_SR1(i2c) & I2C_SR1_BTF)); i2c_send_data(i2c, (uint8_t)(temp_hyst >> 8)); /* MSB */ while (!(I2C_SR1(i2c) & I2C_SR1_BTF)); i2c_send_data(i2c, (uint8_t)(temp_hyst & 0xff00)); /* LSB */ /* After the last byte we have to wait for TxE too. */ while (!(I2C_SR1(i2c) & (I2C_SR1_BTF | I2C_SR1_TxE))); /* Send STOP condition. */ i2c_send_stop(i2c); }
/** * @brief Writes an 8-bit values to an 8-bit registers on an I2C slave starting from registerAddress * @param[in] slaveId The device's I2C slave id * @param[in] registerAddress Address of the device register to write to * @param[in] buffer The buffer with values to write * @return 0 is successful, 1 if not */ int i2c_write_registers(register uint8_t slaveId, register uint8_t registerAddress, register uint8_t registerCount, register uint8_t *buffer){ uint8_t i = 0; /* loop while the bus is still busy */ i2c_wait_while_busy(); /* send I2C start signal and set write direction*/ i2c_send_start(); /* send the slave address and wait for the I2C bus operation to complete */ i2c_send_byte(I2C_WRITE_ADDRESS(slaveId)); /* send the register address */ i2c_send_byte(registerAddress); for(i = 0; i < registerCount; i++) { /* send the register value */ i2c_send_byte(buffer[i]); } /* issue stop signal by clearing master mode. */ i2c_send_stop(); return 0; }
/** * @brief Reads an 8-bit register from an I2C slave */ uint8_t i2c_read_register(register uint8_t slaveId, register uint8_t registerAddress){ /* loop while the bus is still busy */ i2c_wait_while_busy(); /* send I2C start signal and set write direction, also enables ACK */ i2c_send_start(); /* send the slave address and wait for the I2C bus operation to complete */ i2c_send_byte(I2C_WRITE_ADDRESS(slaveId)); /* send the register address */ i2c_send_byte(registerAddress); /* signal a repeated start condition */ i2c_send_repeated_start(); /* send the read address */ i2c_send_byte(I2C_READ_ADDRESS(slaveId)); /* switch to receive mode but disable ACK because only one data byte will be read */ i2c_enter_receive_mode_without_ack(); /* read a dummy byte to drive the clock */ i2c_read_dummy_byte(); /* stop signal */ i2c_send_stop(); /* fetch the last received byte */ register uint8_t result = I2C0->D; return result; }
void i2c_write_byte(uint8_t dev, uint8_t addr, uint8_t data){ if(i2c_send_start()!=0) return; if(i2c_send_addr(dev,TW_WRITE)!=0) return; if(i2c_send_data(addr)!=0) return ; if(i2c_send_data(data)!=0) return; i2c_send_stop(); }
void i2c_write_word(uint8_t dev, uint8_t addr,uint16_t data){ if(i2c_send_start()!=0) return; if(i2c_send_addr(dev,TW_WRITE)!=0) return; if(i2c_send_data(addr)!=0) return; if(i2c_send_data(data & 0xff)!=0) return; if(i2c_send_data(((data & 0xff00)>>8))!=0) return; i2c_send_stop(); }
bool i2c_probe (uint8_t chip_id) { i2c_send_start (); int status = i2c_write_byte ((chip_id << 1) | I2C_WRITE_OPER); i2c_send_stop (); return status == 0; }
/** * @brief Reads multiple 8-bit registers from an I2C slave * @param[in] slaveId The slave device ID * @param[in] startRegisterAddress The first register address * @param[in] registerCount The number of registers to read; Must be greater than or equal to two. * @param[out] buffer The buffer to write into * @return 0 is successful, 1 if not */ static int i2c_read_registers_internal(register uint8_t slaveId, register uint8_t startRegisterAddress, register uint8_t registerCount, uint8_t *const buffer){ if(registerCount < 2) return -1; /* loop while the bus is still busy */ i2c_wait_while_busy(); /* send I2C start signal and set write direction, also enables ACK */ i2c_send_start(); /* send the slave address and wait for the I2C bus operation to complete */ i2c_send_byte(I2C_WRITE_ADDRESS(slaveId)); /* send the register address */ i2c_send_byte(startRegisterAddress); /* signal a repeated start condition */ i2c_send_repeated_start(); /* send the read address */ i2c_send_byte(I2C_READ_ADDRESS(slaveId)); /* switch to receive mode and assume more than one register */ i2c_enter_receive_mode_with_ack(); /* read a dummy byte to drive the clock */ i2c_read_dummy_byte(); /* for all remaining bytes, read */ --registerCount; uint8_t index = 0; while (--registerCount > 0) { /* fetch and store value */ register uint8_t value = I2C0->D; buffer[index++] = value; /* wait for completion */ i2c_wait(); } /* disable ACK and read second-to-last byte */ i2c_disable_ack(); /* fetch and store value */ buffer[index++] = I2C0->D; /* wait for completion */ i2c_wait(); /* stop signal */ i2c_send_stop(); /* fetch the last received byte */ buffer[index++] = I2C0->D; return 0; }
static int i2c_do_xfer(void *reg_addr, I2cSeg segment) { int res = 0; if (i2c_send_start(reg_addr)) return I2C_TIMEOUT; if (segment.read) res = i2c_read(reg_addr, segment); else res = i2c_write(reg_addr, segment); return i2c_send_stop(reg_addr) || res; }
void ds1721_init() { i2c_init(); i2c_send_start(); i2c_send_byte(DS1721_ADDR | DS1721_WRITE); i2c_send_byte(DS1721_CMD_INIT); i2c_send_stop(); _delay_us(10); }
static int i2c_do_xfer(void *reg_addr, struct i2c_msg segment) { int res = 0; if (i2c_send_start(reg_addr)) return I2C_TIMEOUT; if (segment.flags & I2C_M_RD) res = i2c_read(reg_addr, segment); else res = i2c_write(reg_addr, segment); return i2c_send_stop(reg_addr) || res; }
void read_i2c(uint32_t i2c, uint8_t i2c_addr, uint8_t reg, uint8_t size, uint8_t *data) { int wait; int i; while (i2c_busy(i2c) == 1); while (i2c_is_start(i2c) == 1); /*Setting transfer properties*/ i2c_set_bytes_to_transfer(i2c, 1); i2c_set_7bit_address(i2c, i2c_addr); i2c_set_write_transfer_dir(i2c); i2c_disable_autoend(i2c); /*start transfer*/ i2c_send_start(i2c); wait = true; while (wait) { if (i2c_transmit_int_status(i2c)) { wait = false; } while (i2c_nack(i2c)); /* Some error */ } i2c_send_data(i2c, reg); while (i2c_is_start(i2c) == 1); /*Setting transfer properties*/ i2c_set_bytes_to_transfer(i2c, size); i2c_set_7bit_address(i2c, i2c_addr); i2c_set_read_transfer_dir(i2c); i2c_enable_autoend(i2c); /*start transfer*/ i2c_send_start(i2c); for (i = 0; i < size; i++) { while (i2c_received_data(i2c) == 0); data[i] = i2c_get_data(i2c); } }
/** \brief This function creates a Start condition and sends the * I2C address. * \param[in] read #I2C_READ for reading, #I2C_WRITE for writing * \return status of the I2C operation */ static uint8_t ecc108p_send_slave_address(uint8_t read) { uint8_t sla = device_address | read; uint8_t ret_code = i2c_send_start(); if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS) return ret_code; ret_code = i2c_send_bytes(1, &sla); if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS) (void) i2c_send_stop(); return ret_code; }
static void com_send_start() { /* send start */ i2c_send_start(I2C1); while (!((I2C_SR1(I2C1) & I2C_SR1_SB) & (I2C_SR2(I2C1) & (I2C_SR2_MSL | I2C_SR2_BUSY)))) ; /* send address */ i2c_send_7bit_address(I2C1, current_address, I2C_WRITE); while (!(I2C_SR1(I2C1) & I2C_SR1_ADDR)) ; (void)I2C_SR2(I2C1); selected = true; }
/** \brief This I2C function generates a Wake-up pulse and delays. * \return status of the operation */ uint8_t ecc108p_wakeup(void) { #if !defined(ECC108_GPIO_WAKEUP) && !defined(ECC108_I2C_BITBANG) // Generate wakeup pulse by writing a 0 on the I2C bus. uint8_t dummy_byte = 0; uint8_t i2c_status = i2c_send_start(); if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) return ECC108_COMM_FAIL; // To send eight zero bits it takes 10E6 / I2C clock * 8 us. delay_10us(ECC108_WAKEUP_PULSE_WIDTH - (uint8_t) (1000000.0 / 10.0 / I2C_CLOCK * 8.0)); // We have to send at least one byte between an I2C Start and an I2C Stop. (void) i2c_send_bytes(1, &dummy_byte); i2c_status = i2c_send_stop(); if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) return ECC108_COMM_FAIL; #else # if defined(ECC108_I2C_BITBANG) // Generate wakeup pulse using the GPIO pin that is connected to SDA. I2C_DATA_LOW(); delay_10us(ECC108_WAKEUP_PULSE_WIDTH); I2C_DATA_HIGH(); # else // Generate wakeup pulse by disabling the I2C peripheral and // pulling SDA low. The I2C peripheral gets automatically // re-enabled when calling i2c_send_start(). // PORTD is used on the Microbase. You might have to use another // port for a different target. TWCR = 0; // Disable I2C. //DDRD |= _BV(PD1); // Set SDA as output. //PORTD &= ~_BV(PD1); // Set SDA low. pinMode(SDA, OUTPUT); digitalWrite(SDA, LOW); delay_10us(ECC108_WAKEUP_PULSE_WIDTH); //PORTD |= _BV(PD1); // Set SDA high. digitalWrite(SDA, HIGH); # endif #endif delay_10us(ECC108_WAKEUP_DELAY); return ECC108_SUCCESS; }
int i2c_write (uint8_t chip_id, uint8_t reg_addr, const uint8_t* buffer, uint16_t len) { int status = 0; /* send 1st chip internal register address (pointer register) */ if (status == 0) i2c_send_start (); if (status == 0) status = i2c_write_byte (chip_id << 1 | I2C_WRITE_OPER); if (status == 0) status = i2c_write_byte (reg_addr); /* write next the buffer into the chip */ while ((status == 0) && (len > 0)) { len--; status = i2c_write_byte (*buffer++); } i2c_send_stop (); return status; }