Need help understanding TwoWire protocol

I am trying to learn about TwoWire protocol, so I get an Atmega datasheet and a 24C02C serial eeprom.

I am not sure where I am getting wrong at, whether the address(location to store data, not the address to access the slave) or the TWDR register. If I read correctly, TWDR is an 8-bit register.

So to write the address of eeprom for data to be written to, I do this

uint8_t I2C_writeData(uint8_t data)
{
	// load data into data register
	TWDR = data;
	// start transmission of data
	TWCR = (1<<TWINT) | (1<<TWEN);
	// wait for end of transmission
	while( !(TWCR & (1<<TWINT)) );
	
	if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
	
	return 0;
}

However, in the datasheet of the 24C02C, it states it needs a WORD address which is 16-bit, but TWDR is only 8-bit.

So in my main sketch, if I do this

#include <myTWI.h>

#define DEVICEADDRESS 0xA0

unsigned char data;

void setup() {
  Serial.begin(9600);
  I2C_init();

  //writing
  I2C_start();
  I2C_writeAddress(DEVICEADDRESS | WRITE);
 //write upper byte
  I2C_writeData(0x01>>8); //write upper byte
  I2C_writeData(0x01); //write lower byte
  I2C_writeData('A');
  I2C_stop();

  delay(10);

  //reading
  I2C_start();
  I2C_writeAddress(DEVICEADDRESS | WRITE);
  I2C_writeData(0x01>>8); //write upper byte
  I2C_writeData(0x01);
  I2C_restart();
  I2C_writeAddress(DEVICEADDRESS | READ);
  data = I2C_read_nack();
  I2C_stop();
  Serial.print(data, HEX);
}

void loop() {
}

The real data which is 'A', won't be written. It writes 1, correspondence to "I2C_writeData(0x01)"

It works fine it I remove all the upper byte write, aka "I2C_writeData(0x01>>8)"

So, what I am getting wrong here?

As for reference
*READ and WRITE is declared in myI2C.h
*my poorly written I2C.cpp

#include <avr/io.h>
#include <compat/twi.h>

#include "Arduino.h"

#include "myI2C.h"

void I2C_init(void)
{
	digitalWrite(SDA, 1);
	digitalWrite(SCL, 1);
	TWBR = 72; //fixed for now
}

void I2C_start(void) // transmit address
{
			// reset TWI control register
	TWCR = 0;
	// transmit START condition 
	TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
	// wait for end of transmission
	while( !(TWCR & (1<<TWINT)) );
	
	// check if the start condition was successfully transmitted
	if((TWSR & 0xF8) != TW_START){ return 1; }
	
	return 0;
}

void I2C_restart(void)
{ 
	TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
	// wait for end of transmission
	while( !(TWCR & (1<<TWINT)) );
	
	if( (TWSR & 0xF8) != TW_REP_START ){ return 1; }
	
	return 0;
}

uint8_t I2C_read_nack(void)
{
	TWCR = (1<<TWINT) | (1<<TWEN);
	while( !(TWCR & (1<<TWINT)) );
	
	return TWDR;
}

uint8_t I2C_read_ack(void)
{
	// start TWI module and acknowledge data after reception
	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA); 
	// wait for end of transmission
	while( !(TWCR & (1<<TWINT)) );
	// return received data from TWDR
	return TWDR;
}

uint8_t I2C_writeAddress(uint8_t address)
{
	// load data into data register
	TWDR = address;
	// start transmission of data
	TWCR = (1<<TWINT) | (1<<TWEN);
	// wait for end of transmission
	while( !(TWCR & (1<<TWINT)) );
	
	if( (TWSR & 0xF8) != TW_MT_SLA_ACK ){ return 1; }
	
	return 0;
}

uint8_t I2C_writeData(uint8_t data)
{
	// load data into data register
	TWDR = data;
	// start transmission of data
	TWCR = (1<<TWINT) | (1<<TWEN);
	// wait for end of transmission
	while( !(TWCR & (1<<TWINT)) );
	
	if( (TWSR & 0xF8) != TW_MT_DATA_ACK ){ return 1; }
	
	return 0;
}

void I2C_stop(void)
{
	// transmit STOP condition
	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
}

Hi,
Have you looked at this ?

or googled ?

Tom.. :slight_smile:

Hi Tom, I looked through that but that one uses the built in Wire library which is based on the TWI library.

I wanted to stay away from the standard library as I want to learn TWI/I2C from scratch. It is necessary for my daily job as I might need to write the driver for a device if there isn't one. I purposely choose a device like 24C02C since I think it's pretty simple.

I will go through the datasheet again for now as no one seems to give any idea.

Nick Gammon's I2C tutorial

@dougp
Thanks for the tutorial. I already went through Nick's but he also used the standard Wire library which isn't really what I was finding. I know that the other details in his tutorial demonstrate I2C pretty well.

Anyway, after some reading again in the datasheet, the word address actually means 8-bit and not 16-bit even though it said word. A bit confusing for me as I thought word means 16-bit unsigned integer.