void i2cInit(void) { // set i2c bit rate to 40KHz i2cSetBitrate(100); // enable TWI (two-wire interface) sbi(TWCR, TWEN); //initialize i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x2D); //power register i2cWaitForComplete(); i2cSendByte(0x08); //measurement mode i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x31); //data format i2cWaitForComplete(); i2cSendByte(0x08); //full resolution i2cWaitForComplete(); i2cSendStop(); }
void magnetometer_init(void) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x3C); //write to HMC i2cWaitForComplete(); i2cSendByte(0x00); //mode register i2cWaitForComplete(); i2cSendByte(0x70); //8 average, 15Hz, normal measurement i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x3C); //write to HMC i2cWaitForComplete(); i2cSendByte(0x01); //mode register i2cWaitForComplete(); i2cSendByte(0xA0); //gain = 5 i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x3C); //write to HMC i2cWaitForComplete(); i2cSendByte(0x02); //mode register i2cWaitForComplete(); i2cSendByte(0x00); //continuous measurement mode i2cWaitForComplete(); i2cSendStop(); }
void accelerometer_init(void) { //initialize i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x2D); //power register i2cWaitForComplete(); i2cSendByte(0x08); //measurement mode i2cWaitForComplete(); i2cSendStop(); i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x31); //data format i2cWaitForComplete(); i2cSendByte(0x08); //full resolution i2cWaitForComplete(); i2cSendStop(); }
uint16_t x_accel(void) { //0xA6 for a write //0xA7 for a read uint8_t dummy, xh, xl; uint16_t xo; //0x32 data registers i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x32); //X0 data register i2cWaitForComplete(); i2cSendStop(); //repeat start i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA7); //read from ADXL i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xl = i2cGetReceivedByte(); //x low byte i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); dummy = i2cGetReceivedByte(); //must do a multiple byte read? i2cWaitForComplete(); i2cSendStop(); //0x33 data registers i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x33); //X1 data register i2cWaitForComplete(); i2cSendStop(); //repeat start i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA7); //read from ADXL i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xh = i2cGetReceivedByte(); //x high byte i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); dummy = i2cGetReceivedByte(); //must do a multiple byte read? i2cWaitForComplete(); i2cSendStop(); xo = xl|(xh << 8); return xo; }
uint16_t y_accel(void) { //0xA6 for a write //0xA7 for a read uint8_t dummy, yh, yl; uint16_t yo; //0x34 data registers i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x34); //Y0 data register i2cWaitForComplete(); i2cSendStop(); //repeat start i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA7); //read from ADXL i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); yl = i2cGetReceivedByte(); //x low byte i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); dummy = i2cGetReceivedByte(); //must do a multiple byte read? i2cWaitForComplete(); i2cSendStop(); //0x35 data registers i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x35); //Y1 data register i2cWaitForComplete(); i2cSendStop(); //repeat start i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA7); //read from ADXL i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); yh = i2cGetReceivedByte(); //y high byte i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); dummy = i2cGetReceivedByte(); //must do a multiple byte read? i2cWaitForComplete(); i2cSendStop(); yo = yl|(yh << 8); return yo; }
uint16_t z_accel(void) { //0xA6 for a write //0xA7 for a read uint8_t dummy, zh, zl; uint16_t zo; //0x36 data registers i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x36); //Z0 data register i2cWaitForComplete(); i2cSendStop(); //repeat start i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA7); //read from ADXL i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); zl = i2cGetReceivedByte(); //z low byte i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); dummy = i2cGetReceivedByte(); //must do a multiple byte read? i2cWaitForComplete(); i2cSendStop(); //0x37 data registers i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x37); //Z1 data register i2cWaitForComplete(); i2cSendStop(); //repeat start i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA7); //read from ADXL i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); zh = i2cGetReceivedByte(); //z high byte i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); dummy = i2cGetReceivedByte(); //must do a multiple byte read? i2cWaitForComplete(); i2cSendStop(); zo = zl|(zh << 8); return zo; }
uint16_t z_gyro(void) { uint16_t xh, xl, data; cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ITG3200_W); // write i2cWaitForComplete(); i2cSendByte(0x21); // z high address i2cWaitForComplete(); i2cSendStart(); i2cSendByte(ITG3200_R); // read i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); xh = i2cGetReceivedByte(); // Get MSB result i2cWaitForComplete(); i2cSendStop(); cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ITG3200_W); // write i2cWaitForComplete(); i2cSendByte(0x22); // z low address i2cWaitForComplete(); i2cSendStart(); i2cSendByte(ITG3200_R); // read i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); xl = i2cGetReceivedByte(); // Get LSB result i2cWaitForComplete(); i2cSendStop(); data = xl|(xh << 8); cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI return data; }
// USED TO GET VALUES FROM I2C void i2cMasterTransferNI(u08 deviceAddr, u08 sendlength, u08* senddata, u08 receivelength, u08* receivedata) { // disable TWI interrupt cbi(TWCR, TWIE); // send start condition i2cSendStart(); i2cWaitForComplete(); // if there's data to be sent, do it if(sendlength) { // send device address with write i2cSendByte( deviceAddr & 0xFE ); i2cWaitForComplete(); // send data while(sendlength) { i2cSendByte( *senddata++ ); i2cWaitForComplete(); sendlength--; } } // if there's data to be received, do it if(receivelength) { // send repeated start condition i2cSendStart(); i2cWaitForComplete(); // send device address with read i2cSendByte( deviceAddr | 0x01 ); i2cWaitForComplete(); // accept receive data and ack it while(receivelength > 1) { i2cReceiveByte(TRUE); i2cWaitForComplete(); *receivedata++ = i2cGetReceivedByte(); // decrement length receivelength--; } // accept receive data and nack it (last-byte signal) i2cReceiveByte(FALSE); i2cWaitForComplete(); *receivedata++ = i2cGetReceivedByte(); } // transmit stop condition // leave with TWEA on for slave receiving i2cSendStop(); while( !(inb(TWCR) & BV(TWSTO)) ); // enable TWI interrupt sbi(TWCR, TWIE); }
uint8_t Daisy23::mpr_read(uint8_t address) { byte data; i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xB4); // write 0xB4 i2cWaitForComplete(); i2cSendByte(address); // write register address i2cWaitForComplete(); i2cSendStart(); i2cSendByte(0xB5); // write 0xB5 i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); data = i2cGetReceivedByte(); // Get MSB result i2cWaitForComplete(); i2cSendStop(); cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI return data; }
char ITG3200Read(unsigned char address) { char data; cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ITG3200_W); // write 0xD2 i2cWaitForComplete(); i2cSendByte(address); // write register address i2cWaitForComplete(); i2cSendStart(); i2cSendByte(ITG3200_R); // write 0xD3 i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); data = i2cGetReceivedByte(); // Get MSB result i2cWaitForComplete(); i2cSendStop(); cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI return data; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Maps the selected page to the device & address, and writes the device and address // bytes to the device, leaving it in a state to accept more data. EE_STATUS __writeActiveAddress(uint16_t page) { // map device and address to selected page ee_mapdevice(page); // send start condition i2cSendStart(); i2cWaitForComplete(); // send device address with write i2cSendByte(_device & I2C_WRITE); i2cWaitForComplete(); // check if device is present and live // device did not ACK it's address, // data will not be transferred // return error if (i2cGetStatus() != TW_MT_SLA_ACK) { i2cSendStop(); return I2C_ERROR_NODEV; } // address MSB i2cSendByte(_address >> 8); i2cWaitForComplete(); // address LSB i2cSendByte(_address & 0xFF); i2cWaitForComplete(); return I2C_OK; }
int16_t read_adxl345(char reg_adr) { char lsb, msb; i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ADXL345_W); // write to this I2C address, R/*W cleared i2cWaitForComplete(); i2cSendByte(reg_adr); //Read from a given address i2cWaitForComplete(); i2cSendStart(); i2cSendByte(ADXL345_R); // read from this I2C address, R/*W Set i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); lsb = i2cGetReceivedByte(); //Read the LSB data i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); msb = i2cGetReceivedByte(); //Read the MSB data i2cWaitForComplete(); i2cSendStop(); return( (msb<<8) | lsb); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ee_poll(void) { /* ACKNOWLEDGE POLLING: Once the internally timed write cycle has started and the EEPROM inputs are disabled, acknowledge polling can be initiated. This involves sending a start condition followed by the device address word. The read/write bit is representative of the operation desired. Only if the internal write cycle has completed will the EEPROM respond with a zero, allowing the read or write sequence to continue. */ while(1) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(_device & I2C_WRITE); i2cWaitForComplete(); if (i2cGetStatus() == TW_MT_SLA_ACK) { i2cSendStop(); //i2cWaitForComplete(); break; } } }
byte DetectTouch::mpr121Read(uint8_t address) { byte data; i2cSendStart(); i2cWaitForComplete(); i2cSendByte(i2c_address); // write 0xB4 i2cWaitForComplete(); i2cSendByte(address); // write register address i2cWaitForComplete(); i2cSendStart(); i2cSendByte(i2c_address+1); // write 0xB5 i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); data = i2cGetReceivedByte(); // Get MSB result i2cWaitForComplete(); i2cSendStop(); cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI return data; }
/* Writes a single byte (data) into address */ void i2cWriteRegister(uint8_t i2c_7bit_address, uint8_t address, uint8_t data) { i2cSendStart(); i2cSendWriteAddress(i2c_7bit_address); i2cSendData(address); // write register address i2cSendData(data); i2cSendStop(); }
void magnetometer(void) { /* The magnetometer values must be read consecutively in order to move the magnetometer pointer. Therefore the x, y, and z outputs need to be kept in this function. To read the magnetometer values, call the function magnetometer(), then global vars x_mag, y_mag, z_mag. */ magnetometer_init(); uint8_t xh, xl, yh, yl, zh, zl; //must read all six registers plus one to move the pointer back to 0x03 i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x3D); //write to HMC i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xh = i2cGetReceivedByte(); //x high byte i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); xl = i2cGetReceivedByte(); //x low byte i2cWaitForComplete(); x_mag = xl|(xh << 8); i2cReceiveByte(TRUE); i2cWaitForComplete(); zh = i2cGetReceivedByte(); i2cWaitForComplete(); //z high byte i2cReceiveByte(TRUE); i2cWaitForComplete(); zl = i2cGetReceivedByte(); //z low byte i2cWaitForComplete(); z_mag = zl|(zh << 8); i2cReceiveByte(TRUE); i2cWaitForComplete(); yh = i2cGetReceivedByte(); //y high byte i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); yl = i2cGetReceivedByte(); //y low byte i2cWaitForComplete(); y_mag = yl|(yh << 8); i2cSendByte(0x3D); //must reach 0x09 to go back to 0x03 i2cWaitForComplete(); i2cSendStop(); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Initiates an async read operation void ee_readAHandler(void) { switch(_asyncStep) { // send a start signal case ASYNC_NEXT_START: _asyncStep = ASYNC_NEXT_DEVICE; i2cSendStartAsync(ee_readAHandler); break; // send SLA+R case ASYNC_NEXT_DEVICE: if (i2cGetStatus() != TW_START) { _asyncError(); break; } _asyncStep = ASYNC_NEXT_NACK; i2cSendByteAsync(_device | I2C_READ, ee_readAHandler); break; // setup TWI module to NACK the response case ASYNC_NEXT_NACK: if (i2cGetStatus() != TW_MR_SLA_ACK) { _asyncError(); break; } _asyncStep = ASYNC_NEXT_READ; i2cNackA(ee_readAHandler); break; // capture the received data case ASYNC_NEXT_READ: if (i2cGetStatus() != TW_MR_DATA_NACK) { _asyncError(); break; } // read received data _data = i2cGetReceivedByte(); i2cSendStop(); // mark transaction as complete _eeComplete(_data); // increment the address pointer incrementAddress(); break; } }
int8_t i2cSingleWrite(uint8_t addr,uint8_t data) { if(device_addr > 0xFf)return I2C_ERR_ADDRESS_LONG; i2cSendStop(); i2cSendStart(); switch(i2cSendByte(device_addr | I2C_WRITE)) { case TW_MT_SLA_ACK: break; case TW_MT_SLA_NACK: printf("Recieve Nack\n"); return I2C_ERR_NACK; default: return I2C_ERR_UNKNOWN; } switch(i2cSendByte(addr)) { case TW_MT_DATA_ACK: break; case TW_MT_DATA_NACK: printf("Recieve Nack\n"); return I2C_ERR_NACK; default: return I2C_ERR_UNKNOWN; } switch(i2cSendByte(data)) { case TW_MT_DATA_ACK: break; case TW_MT_DATA_NACK: printf("Recieve Nack\n"); return I2C_ERR_NACK; default: return I2C_ERR_UNKNOWN; } i2cSendStop(); return 1; }
/* Writes num_to_send bytes of data starting at address */ void i2cWriteRegisters(uint8_t i2c_7bit_address, uint8_t address, uint8_t num_to_send, const uint8_t *data) { i2cSendStart(); i2cSendWriteAddress(i2c_7bit_address); i2cSendData(address); // write register address for (int j=0; j<num_to_send; j++) { i2cSendData(data[j]); } i2cSendStop(); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Set the current address EE_STATUS ee_setpage(uint16_t page) { // set current address on device __writeActiveAddress(page); // transmit stop condition // leave with TWEA on for slave receiving i2cSendStop(); i2cWaitForStop(); //i2cWaitForComplete(); return I2C_OK; }
uint8_t i2cMasterReceiveNI(uint8_t deviceAddr, uint8_t length, uint8_t *data) { uint8_t retval = I2C_OK; // disable TWI interrupt cbi(TWCR, TWIE); // send start condition i2cSendStart(); i2cWaitForComplete(); // send device address with read i2cSendByte(deviceAddr | 0x01); i2cWaitForComplete(); //rprintf("receive TWSR = 0x%x\n", TWSR); // check if device is present and live if (inb(TWSR) == TW_MR_SLA_ACK) { // accept receive data and ack it while(length > 1) { i2cReceiveByte(TRUE); i2cWaitForComplete(); *data++ = i2cGetReceivedByte(); // decrement length length--; } // accept receive data and nack it (last-byte signal) i2cReceiveByte(FALSE); i2cWaitForComplete(); *data++ = i2cGetReceivedByte(); } else { // device did not ACK it's address, // data will not be transferred // return error retval = I2C_ERROR_NODEV; } // transmit stop condition // leave with TWEA on for slave receiving i2cSendStop(); // enable TWI interrupt sbi(TWCR, TWIE); return retval; }
void gyro_init(void) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ITG3200_W); // write 0xB4 i2cWaitForComplete(); i2cSendByte(0x3E); // write register address i2cWaitForComplete(); i2cSendByte(0x80); i2cWaitForComplete(); i2cSendStop(); delay_ms(10); i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ITG3200_W); // write 0xB4 i2cWaitForComplete(); i2cSendByte(0x16); // write register address i2cWaitForComplete(); i2cSendByte(0x18); // DLPF_CFG = 0, FS_SEL = 3 i2cWaitForComplete(); i2cSendStop(); delay_ms(10); i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ITG3200_W); // write 0xB4 i2cWaitForComplete(); i2cSendByte(0x3E); // write register address i2cWaitForComplete(); i2cSendByte(0x00); i2cWaitForComplete(); i2cSendStop(); }
void Daisy23::mpr_send(unsigned char address, unsigned char data) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ADDR);// write 0xB4 i2cWaitForComplete(); i2cSendByte(address); // write register address i2cWaitForComplete(); i2cSendByte(data); i2cWaitForComplete(); i2cSendStop(); }
void DetectTouch::mpr121Write(unsigned char address, unsigned char data) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(i2c_address);// write 0xB4 i2cWaitForComplete(); i2cSendByte(address); // write register address i2cWaitForComplete(); i2cSendByte(data); i2cWaitForComplete(); i2cSendStop(); }
//Setup ADXL345 for constant measurement mode void init_adxl345(void) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ADXL345_W); //write to ADXL345 i2cWaitForComplete(); i2cSendByte(0x2D); //Write to Power CTL register i2cWaitForComplete(); i2cSendByte( (1<<3) ); //Set the measure bit on D3 i2cWaitForComplete(); i2cSendStop(); }
void ITG3200Write(unsigned char address, unsigned char data) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ITG3200_W); // write 0xB4 i2cWaitForComplete(); i2cSendByte(address); // write register address i2cWaitForComplete(); i2cSendByte(data); i2cWaitForComplete(); i2cSendStop(); }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Performs an I2C acknoledge for the EEPROM. If the device is busy, it will NACK bool ee_busy(void) { i2cSendStart(); i2cWaitForComplete(); i2cSendByte(_device & I2C_WRITE); i2cWaitForComplete(); if (i2cGetStatus() == TW_MT_SLA_ACK) { i2cSendStop(); return false; } return true; }
//Read a tmp102 sensor on a given temp_number or channel int16_t tmp102Read(void) { uint8_t msb, lsb; int16_t temp; i2cSendStart(); // send start condition i2cWaitForComplete(); i2cSendByte(TMP102_WRITE); // send WRITE address of TMP102 i2cWaitForComplete(); i2cSendByte(0x00); // set TMP102 pointer register to 0 (read temperature) i2cWaitForComplete(); i2cSendStart(); // send repeated start condition i2cWaitForComplete(); i2cSendByte(TMP102_READ); // send READ address of TMP102 i2cWaitForComplete(); i2cReceiveByte(true); // receives one byte from the bus and ACKs it i2cWaitForComplete(); msb = i2cGetReceivedByte(); // reads the MSB (it is a 12 bit value!) i2cWaitForComplete(); i2cReceiveByte(false); // receives one byte from the bus and NAKs it (last one) i2cWaitForComplete(); lsb = i2cGetReceivedByte(); // reads the LSB i2cWaitForComplete(); i2cSendStop(); // send stop condition TWCR = 0; // stop everything // Convert the number to an 8-bit degree Celsius value temp = (msb<<8) | lsb; // combine those two values into one 16 bit value temp >>= 4; // the values are left justified; fix that by shifting 4 right // negative numbers are represented in two's complement, but we just shifted the value and thereby potentially messed it up if(temp & (1<<11)) // Hence: if it is a negative number temp |= 0xF800; // restore the uppermost bits // The 12 bit value has 0.0625°C precision, which is too much for what we want (and the sensor is anyways only about 0.5°C precise) // 0.0625 is 1/16 -> Dividing by 16 leaves 1°C precision for the output. Note that shifting >> 4 might go wrong here for negative numbers. temp /= 16; return(temp); }
uint8_t i2cMasterSendNI(uint8_t deviceAddr, uint8_t length, uint8_t const *data) { uint8_t retval = I2C_OK; // disable TWI interrupt cbi(TWCR, TWIE); // send start condition i2cSendStart(); i2cWaitForComplete(); // send device address with write i2cSendByte(deviceAddr & 0xFE); i2cWaitForComplete(); // check if device is present and live if (inb(TWSR) == TW_MT_SLA_ACK) { // send data while (length) { i2cSendByte(*data++); i2cWaitForComplete(); length--; } } else { // device did not ACK it's address, // data will not be transferred // return error retval = I2C_ERROR_NODEV; } // transmit stop condition // leave with TWEA on for slave receiving i2cSendStop(); while (!(inb(TWCR) & BV(TWSTO))) ; // enable TWI interrupt sbi(TWCR, TWIE); return retval; }
// read a single byte from address and return it as a byte uint8_t i2cReadRegister(uint8_t i2c_7bit_address, uint8_t address) { uint8_t data; i2cSendStart(); i2cSendWriteAddress(i2c_7bit_address); i2cSendData(address); // write register address i2cSendRepeatedStart(); // repeated start i2cSendReadAddress(i2c_7bit_address); i2cReceiveByte(0); data = i2cGetReceivedByte(); // Get result i2cSendStop(); cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI return data; }