Frustrating TWI

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

I'm trying to get some example TWI code to work on a an EEPROM chip and I'm having some issues.

The EEPROM is 24AA08.

I'm just trying to write a few bytes and then read back the result but I keep getting 0x00 or 0xFF. I've checked the TWI lines on the scope and they're both looking good. I can see the data getting passed. I've also tried different baud rates and clock rates. I wasted about 8 hours on this today :evil: :evil: :evil:

// Include Files
#include 	
#include 	
#include	
#include 	
#include 	"../../Drivers/System/System.h"	
#include 	"../../Drivers/Board/Board.h"
#include "avr_compiler.h"
#include "twi_master_driver.h"

/* Set up stream */
static FILE USART_TX = FDEV_SETUP_STREAM (USART_Printf, NULL, _FDEV_SETUP_WRITE);

// Macros
#define 	SLAVE_ADDRESS		0x50
#define		WORD_ADDRESS		0x13 // Arbitrary write address

/*! CPU speed 2MHz, BAUDRATE 100kHz and Baudrate Register Settings */
#define CPU_SPEED       32000000
#define BAUDRATE	100000
#define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)


/* Global variables */
TWI_Master_t twiMaster;    /*!< TWI master module. */

/* Function Prototypes */
void Setup_Hardware(void);

int main (void)
{
	
	uint8_t i;
	uint8_t TxBuffer[9] = {WORD_ADDRESS, 0x55, 0xAA, 0xF0, 0x0F, 0xB0, 0x0B, 0xDE, 0xAD};
	uint8_t RxBuffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
	
	Setup_Hardware();
	stdout = &USART_TX;
	
	/* Initialize TWI master. */
	TWI_MasterInit(&twiMaster, &TWIE, TWI_MASTER_INTLVL_LO_gc, TWI_BAUDSETTING);
	
	TWI_MasterWriteRead(&twiMaster, SLAVE_ADDRESS, &RxBuffer[0], 8, 0);
	printf("Writing to memory: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", 
	TxBuffer[1],TxBuffer[2],TxBuffer[3],TxBuffer[4],TxBuffer[5],TxBuffer[6],TxBuffer[7], TxBuffer[8]);
	
	while (twiMaster.status != TWIM_STATUS_READY); 
	TWI_MasterWriteRead(&twiMaster, SLAVE_ADDRESS, &TxBuffer[0], 1, 8);
	
	while (twiMaster.status != TWIM_STATUS_READY); 
	for(i = 0; i < 8; i++)
	{
		RxBuffer[i] = twiMaster.readData[i];
	}
	printf("Reading from memory: 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X\n", 
	RxBuffer[0],RxBuffer[1],RxBuffer[2],RxBuffer[3],RxBuffer[4],RxBuffer[5],RxBuffer[6],RxBuffer[7]);
	
	
}

void Setup_Hardware(void)
{
	Set_Clock_To_32MHz_Ext();
	_delay_ms(300);
	LCD_Init();
	LEDs_Init();
	Switches_Init();
	SevenSeg_Init();
	USART_Init();
	Buttons_Init();

	/* Enable low, medium, and high interrupt levels. */
	PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;	

	/* Enable global interrupts */
	sei();
	
	/* Disable Watchdog Timer */
	WDT_Disable();
}

/*! TWIE Master Interrupt vector. */
ISR(TWIE_TWIM_vect)
{
	TWI_MasterInterruptHandler(&twiMaster);
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
SLAVE_ADDRESS 0x50
Unless your TWI code shifts the address left by one (I have seen such code) then it should be 0xA xxx R/W (xxx block address)

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Yeah that's what I had at first but then I changed it to 0x50 per electronic.designer's post. I guess atmel's code left shifts it.

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

Note to self: always write data from the Tx buffer and not the empty Rx buffer.

It works now.

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

Have you kicked your "derrier" hard? :lol:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Gordon,

It sounds like you've solved your problem, but I'll throw in this idea for future I2C/TWI/SPI EEPROM adventures. I have been down this road any number of times with different serial EEPROMs and different processors. Here's one of my "tricks" - actually it's been elevated to the category of "methodology".

There is a basic chicken-&-egg situation implicit in this common place get-the-EEPROM-connected-to-the-processor exercise. You write data to the EEPROM than read it back and either compare it or simply observe the read-back values. They are not equal, now what? Am I writing incorrectly and reading correctly, am I writing correctly but reading back incorrectly, or doing both incorrectly?

My simple divide-and-conquer technique (which came to me in a Flash of Genius one afternoon many years ago after wasting many 8-hour days in a similar manner to your own experience). Program the EEPROM in a standard PROM programmer and test your Read Functions first. Or, Write the EEPROM with your routines and read the EEPROM back in the programmer. In either case the PROM programmer is the "gold-standard" you want to have on hand as you are developing and testing your routines.

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

Quote:
came to me in a Flash of Genius
...or in this case an EEPROM of Genius ... :?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

good idea with the prom programmer, but I don't have one!

js wrote:
Quote:
came to me in a Flash of Genius
...or in this case an EEPROM of Genius ... :?

This made me lol. :o

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

GordonFreeman wrote:
good idea with the prom programmer, but I don't have one!

Your "previous" well tested old Mega project , using the same eeprom. Would do (if you have any).

/Bingo