Atmegs 324pb i2c on PC0 PC1 hangs in receive

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

This is the second day I am trying to communicate over i2c on this atmega baard Digi-Key Part Number ATMEGA324PB-XPRO-ND

with: TLV493D which I tested over i2c on arduino uno, and works just fine.

I pulled up the SCL SDA (PC0 PC1) with 10 Ko resistors.

My code uses  i2c_master from git hub. Small changes due 324, commented out line last 2 lines in

i2c_start(

My code does :

    uint8_t rbuffer[10] = {0};

    i2c_init();
    i2c_start(0x5e << 1 | I2C_READ);
    2c_receive(0x5e, rbuffer, sizeof(rbuffer));  

 

// which ends up in byte by byte receive

 

uint8_t i2c_read_nack(void)
{
    
    // start receiving without acknowledging reception
    TWCR = (1<<TWINT) | (1<<TWEN);
    // wait for end of transmission
    while( !(TWCR & (1<<TWINT)) );  <<<  HANGS HERE....
    // return received data from TWDR
    return TWDR;
}

#define Prescaler 1
#define TWBR_val ((((F_CPU / F_SCL) / Prescaler) - 16 ) / 2)

// my init
void i2c_init(void)
{
    uint8_t frq = F_CPU / ((16 + 2 * TWBR) * Prescaler);
    TWBR = (uint8_t)32;
}

//my start
uint8_t i2c_start(uint8_t 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; 
	}
	
	// load slave address into data register
	TWDR = address;
	// start transmission of address
	TWCR = (1<<TWINT) | (1<<TWEN);
	// wait for end of transmission
	while( !(TWCR & (1<<TWINT)) );
	
	
	// check if the device has acknowledged the READ / WRITE mode
	//// mco uint8_t twst = TW_STATUS & 0xF8;
	//// mco if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;
	
	return 0;
}

  

receive buffer function

uint8_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length)
{
	if (xi2c_start(address | I2C_READ)) return 1;
	
	for (uint16_t i = 0; i < (length-1); i++)
	{
		data[i] = i2c_read_nack();
	}
	data[(length-1)] = i2c_read_nack();
	
	i2c_stop();
	
	return 0;
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

comarius wrote:
commented out line last 2 lines in

 

The best part of i2c is it will tell you what is wrong if you use the return status!

But you commented out the part that returns the status???

 

The other thing I see, when the master reads data from a slave, it must read_ack() each data item, then it must read_nak() the last data item to let the slave know

it must release the bus control back to the master so it can stop() the bus.   Since you read_nak() all items, the slave stops sending data after the first byte, and waits for the master to stop the bus.

(so it looks like it is hung, it's only doing what you told it)

 

Jim

 

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you.

 

1. I commented the code because the 324pb  on this line I  have undefined flags

 

// uint8_t twst = TW_STATUS & 0xF8; 
uint8_t state = TWSR; 
but the state is state 01001000

i2ctwi.c(52,17): info: each undeclared identifier is reported only once for each function it appears in
 'TWS6' undeclared (first use in this function)
          uint8_t twst = TW_STATUS & 0xF8;
                         ^
: 'TWS5' undeclared (first use in this function)
          uint8_t twst = TW_STATUS & 0xF8;
                         ^
 error: 'TWS4' undeclared (first use in this function)
          uint8_t twst = TW_STATUS & 0xF8;
                         ^
rror: 'TWS3' undeclared (first use in this function)
          uint8_t twst = TW_STATUS & 0xF8;

 

 

 

state before reading ack is state 01001000

 

 

 

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)) );  <<< HANGS HERE
	// return received data from TWDR
	return TWDR;
}

By refman: 40001908A-1218154.pdf  page 264

 

 Master rec: SLA+R out, NAK in
state 01001000
 Master rec: SLA+R out, NAK in  then hung  / master receive failed ?

 

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Got it.

The hall device was bad. I plugged in a bmp080 I had in some drawer, and works.

Thank you.