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); }
// 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); }
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; }
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; }
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; }
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; }
//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); }
// Read num_to_read registers sequentially, starting at address // into the dest byte arra void i2cReadRegisters(uint8_t i2c_7bit_address, uint8_t address, uint8_t num_to_read, uint8_t * dest) { i2cSendStart(); i2cSendWriteAddress(i2c_7bit_address); i2cSendData(address); // write register address i2cSendRepeatedStart(); // repeated start i2cSendReadAddress(i2c_7bit_address); int j; for (j=0; j<num_to_read-1; j++) { i2cReceiveByte(1); dest[j] = i2cGetReceivedByte(); // Get data } i2cReceiveByte(0); dest[j] = i2cGetReceivedByte(); // Get data i2cSendStop(); cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI }
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(); }
//Reads two sequential 8 bit values from a given I2C address //Returns one 16 bit value uint16_t i2cRead_16(unsigned char i2c_address, unsigned char register_address) { char msb, lsb; uint16_t data; i2cSendStart(); i2cWaitForComplete(); i2cSendByte(i2c_address<<1 & 0x0FE); // write to this I2C address, R/*W cleared i2cWaitForComplete(); i2cSendByte(register_address); // write register address i2cWaitForComplete(); i2cSendStart(); i2cSendByte(i2c_address<<1 | 0x01); // read from this I2C address, R/*W Set i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); lsb = i2cGetReceivedByte(); // Get MSB result i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); msb = i2cGetReceivedByte(); // Get LSB result i2cWaitForComplete(); i2cSendStop(); data = msb << 8; data |= lsb; return data; }
// 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; }
void self_test(void) { //MAGNETOMETER uint8_t a,b,c,d,e,f,g,h,i,j,k,l; i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0x3D); //read from HMC i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); status = i2cGetReceivedByte(); i2cWaitForComplete(); if(status == 0x10) { printf("MAG: GOOD\n\r"); }else printf("MAG: BAD\n\r"); a = i2cGetReceivedByte(); i2cWaitForComplete(); b = i2cGetReceivedByte(); i2cWaitForComplete(); c = i2cGetReceivedByte(); i2cWaitForComplete(); d = i2cGetReceivedByte(); i2cWaitForComplete(); e = i2cGetReceivedByte(); i2cWaitForComplete(); f = i2cGetReceivedByte(); i2cWaitForComplete(); g = i2cGetReceivedByte(); i2cWaitForComplete(); h = i2cGetReceivedByte(); i2cWaitForComplete(); i = i2cGetReceivedByte(); i2cWaitForComplete(); j = i2cGetReceivedByte(); i2cWaitForComplete(); k = i2cGetReceivedByte(); i2cWaitForComplete(); l = i2cGetReceivedByte(); i2cWaitForComplete(); i2cSendStop(); //ACCELEROMETER uint8_t x, dummy; //0x32 data registers i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x00); //X0 data register i2cWaitForComplete(); i2cSendStop(); //repeat start i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA7); //read from ADXL i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); x = i2cGetReceivedByte(); i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); dummy = i2cGetReceivedByte(); i2cWaitForComplete(); i2cSendStop(); if(x == 0xE5) { printf("ACCEL: GOOD\n\r"); }else printf("ACCEL: BAD\n\r"); //GYROS printf("*must cycle power to perform another test*"); }
void self_test(void) { //MAGNETOMETER uint8_t xh, xl, yh, yl, zh, zl, hmc_flag = 0; x_mag = 0; y_mag = 0; z_mag = 0; magnetometer_init(); //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(); //if it gets to this point and there are values in x,y,z_mag, we can assume part is responding correctly if((x_mag == y_mag) && (y_mag == z_mag)) hmc_flag = 0xFF; else hmc_flag = 0; //ACCELEROMETER uint8_t x, dummy; //0x32 data registers i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA6); //write to ADXL i2cWaitForComplete(); i2cSendByte(0x00); //X0 data register i2cWaitForComplete(); i2cSendStop(); //repeat start i2cSendStart(); i2cWaitForComplete(); i2cSendByte(0xA7); //read from ADXL i2cWaitForComplete(); i2cReceiveByte(TRUE); i2cWaitForComplete(); x = i2cGetReceivedByte(); i2cWaitForComplete(); i2cReceiveByte(FALSE); i2cWaitForComplete(); dummy = i2cGetReceivedByte(); i2cWaitForComplete(); i2cSendStop(); /////////////////////////////////// // Gyro//////////////////////////// /////////////////////////////////// char data; cbi(TWCR, TWEN); // Disable TWI sbi(TWCR, TWEN); // Enable TWI i2cSendStart(); i2cWaitForComplete(); i2cSendByte(ITG3200_W); // write 0xD2 i2cWaitForComplete(); i2cSendByte(0x00); // who am i 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 int gyro_flag = 0; int mag_flag = 0; int accel_flag = 0; if(data == 0x69) { printf("ITG: GOOD\n\r"); gyro_flag = 1; }else printf("ITG: BAD\n\r"); if(hmc_flag == 0) { printf("HMC: GOOD\n\r"); mag_flag = 1; }else printf("HMC: BAD\n\r"); if(x == 0xE5) { printf("ADXL: GOOD\n\r"); accel_flag = 1; }else printf("ADXL: BAD\n\r"); if(gyro_flag ==1 && mag_flag == 1 && accel_flag == 1) { sbi(PORTB, 5); delay_ms(1000); cbi(PORTB, 5); delay_ms(1000); sbi(PORTB, 5); delay_ms(1000); cbi(PORTB, 5); delay_ms(1000); sbi(PORTB, 5); delay_ms(1000); cbi(PORTB, 5); delay_ms(1000); sbi(PORTB, 5); delay_ms(1000); cbi(PORTB, 5); delay_ms(1000); sbi(PORTB, 5); delay_ms(1000); cbi(PORTB, 5); gyro_flag = 0; mag_flag = 0; accel_flag = 0; }else sbi(PORTB, 5); //while(!(UCSR0A & (1 << RXC0))); config_menu(); }
// ************ EDP Master operations ************ u08 edpSendCommand(u08 deviceAddr, u08 cmdLength, EdpCommand* edpCommand) { EdpReply* edpCommandReply = (EdpReply*)EdpCommandReplyBuffer; u08* sendData; u08* replyData; u08 replyLength; u08 checksum; // initialize response variables edpCommandReply->Length = 0; EdpCommandReplyChecksum = 0; #ifdef EDP_DEBUG rprintf("\r\nBegin EdpSendCommand, TWSR:0x%x\r\n",inb(TWSR)); #endif // disable TWI interrupt cbi(TWCR, TWIE); // clear TWI interface //outb(TWCR, (inb(TWCR)&TWCR_CMD_MASK)); // send start condition i2cSendStart(); i2cWaitForComplete(); #ifdef EDP_DEBUG rprintf("Sent Start, TWSR:0x%x\r\n",inb(TWSR)); #endif // send device address with write i2cSendByte( (deviceAddr&0xFE) ); i2cWaitForComplete(); #ifdef EDP_DEBUG rprintf("Sent Device Address+Write, TWSR:0x%x\r\n",inb(TWSR)); #endif // check if device is present and live if( i2cGetStatus() != TW_MT_SLA_ACK) { // device did not ACK it's address, command will not continue // transmit stop condition // leave with TWEA on for slave receiving i2cSendStop(); while( !(inb(TWCR) & BV(TWSTO)) ); #ifdef EDP_DEBUG rprintf("No Device!, Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); #endif // enable TWI interrupt sbi(TWCR, TWIE); // return error return EDP_COMMAND_NODEV; } // send data sendData = (u08*)edpCommand; checksum = 0; while(cmdLength) { i2cSendByte( *sendData ); i2cWaitForComplete(); #ifdef EDP_DEBUG rprintf("Sent Data, TWSR:0x%x\r\n",inb(TWSR)); #endif checksum += *sendData++; cmdLength--; } // send the checksum i2cSendByte( ~checksum ); i2cWaitForComplete(); #ifdef EDP_DEBUG rprintf("Sent Checksum, TWSR:0x%x\r\n",inb(TWSR)); #endif // send repeated start condition i2cSendStart(); i2cWaitForComplete(); #ifdef EDP_DEBUG rprintf("Sent Repeated Start, TWSR:0x%x\r\n",inb(TWSR)); #endif // send device address with read i2cSendByte( deviceAddr|0x01 ); i2cWaitForComplete(); #ifdef EDP_DEBUG rprintf("Sent Device Address+Read, TWSR:0x%x\r\n",inb(TWSR)); #endif // read response code, return NACK i2cReceiveByte(FALSE); i2cWaitForComplete(); #ifdef EDP_DEBUG rprintf("Read Data, TWSR:0x%x\r\n",inb(TWSR)); #endif EdpCommandResponseCode = i2cGetReceivedByte(); if(EdpCommandResponseCode==EDP_RESP_DATA_REPLY) { // a data reply is being sent // send repeated start condition i2cSendStart(); i2cWaitForComplete(); // send device address with read i2cSendByte( deviceAddr|0x01 ); i2cWaitForComplete(); // get length, return ACK i2cReceiveByte(TRUE); i2cWaitForComplete(); edpCommandReply->Length = i2cGetReceivedByte(); // set temp variables replyLength = edpCommandReply->Length; replyData = edpCommandReply->Data; // get data, return ACKs // preset checksum with the datalength byte checksum = replyLength; while(replyLength > 1) { i2cReceiveByte(TRUE); // receive data byte and return ACK i2cWaitForComplete(); *replyData = i2cGetReceivedByte(); checksum += *replyData++; replyLength--; } // get last data (actually the checksum), return NACK (last-byte signal) i2cReceiveByte(FALSE); i2cWaitForComplete(); *replyData = i2cGetReceivedByte(); // add received checksum+1 to our checksum, the result should be zero checksum += (*replyData) + 1; // save the reply checksum EdpCommandReplyChecksum = checksum; } // transmit stop condition // leave with TWEA on for slave receiving i2cSendStop(); while( !(inb(TWCR) & BV(TWSTO)) ); #ifdef EDP_DEBUG rprintf("Sent Stop, TWSR:0x%x\r\n",inb(TWSR)); #endif // enable TWI interrupt sbi(TWCR, TWIE); return EDP_COMMAND_OK; }
void one_byte_r(uint8_t cmd) { i2cSendStart(); i2cWaitForComplete(); delay_us(10); printf("TWSR is: %x\n", (TWSR & 0xFC)); // send slave device address with write i2cSendByte(SLA_W); i2cWaitForComplete(); delay_us(10); printf("TWSR is: %x\n", (TWSR & 0xFC)); TWDR = cmd; TWCR = (1<<TWINT)|(1<<TWEN); i2cWaitForComplete(); delay_us(10); i2cSendStart(); i2cWaitForComplete(); delay_us(10); printf("TWSR is: %x\n", (TWSR & 0xFC)); // send slave device address with write i2cSendByte(SLA_R); i2cWaitForComplete(); delay_us(10); printf("TWSR is: %x\n", (TWSR & 0xFC)); if( inb(TWSR) == TW_MR_SLA_ACK) { i2cReceiveByte(TRUE); i2cWaitForComplete(); delay_us(10); byte1 = i2cGetReceivedByte(); printf("\tbyte1 is: %x\n", byte1); i2cReceiveByte(TRUE); i2cWaitForComplete(); delay_us(10); byte2 = i2cGetReceivedByte(); printf("\tbyte2 is: %x\n", byte2); } else { // device did not ACK it's address, // data will not be transferred // return error //retval = I2C_ERROR_NODEV; } delay_us(10); i2cSendStop(); }