Issues with I2C reading eeprom 24AA32A

Hello

I’m having a problem reading back data from the eeprom, the write works fine, and the i2c trace matches the data sheet of the eeprom, but when i read back the data from the eeprom, the read back looks good in the track and there is the data that i stored, but when I get the data, for example test.data_out, the data is missing,

the project is fairly simple, and it is designed for testing, so it is minimual,

there is au_top, eeprom_241132a, and test_eeprom.

so briefly

in test:

if (!usb_tx_busy)
{
usb_new_tx = 1;
usb_tx_data = test.read_value; // this is the value read from the eeprom first byt
}

which references:

if(!qwiic.busy) {
state.d = state.RSTOP;
qwiic.write = 0;
qwiic.read = 1;
//read_value = 8b00110011; //qwiic.data_out;
read_value = qwiic.data_out; // <= this is the problem, no data received to read_value
}

qwiic references the ic2_controller luc code

attached is a trace of the read back

if you have any ideas that would be most appriciated.

regards

Jeff

Here is the trace of the readback

regards

Jeff

here is the code to the three modules

module au_top (
input clk, // 100MHz clock
input rst_n, // reset button (active low)
output led [8], // 8 user controllable LEDs
input usb_rx, // USB->Serial input
output usb_tx, // USB->Serial output
inout sda, // i2c data
output scl // i2c clock

)

{

sig rst; // reset signal

.clk(clk) {

reset_conditioner reset_cond;
.rst(rst) {
 eeprom_24AA32A  eeprom(.sda(sda));
 test_eeprom test(.sda(sda));
 
 // uart_rx uart_rx(#BAUD(9600), #CLK_FREQ(100000000));    //console 
  uart_tx uart_tx(#BAUD(9600), #CLK_FREQ(100000000));    //console

}

}

always {
reset_cond.in = ~rst_n; // input raw inverted reset signal
rst = reset_cond.out; // conditioned reset
//usb_tx = usb_rx; // echo the serial data
led = 8b11110011;
scl = test.scl;
//test.read_data = 0;

usb_tx = uart_tx.tx;    // connect the output console

// uart_rx.rx = usb_rx; // connect the input console
// usb_tx = usb_rx; // echo the serial data

// USB TX Connections
uart_tx.block    =  0;      // don't block
test.usb_tx_busy =  uart_tx.busy;
uart_tx.new_data =  test.usb_new_tx;
uart_tx.data     =  test.usb_tx_data;

eeprom.cntl_byte_write = 0;
eeprom.cntl_byte_read = 0;
eeprom.high_addr_byte = 0;
eeprom.low_addr_byte = 0;
eeprom.write = 0;
eeprom.read = 0;
eeprom.data_byte = 0;
// USB RX Connections
//test.usb_new_rx  = uart_rx.new_data;
//test.usb_rx_data = uart_rx.data;
test.read_value = 0;

}
module eeprom_24AA32A

(
input clk, // clock
input rst, // reset
input write, // write enabled
input read, // read enabled
output busy, // busy indicator 1 = busy
inout sda, // i2c data
output scl , // i2c clock
input cntl_byte_write[8],
input high_addr_byte[8],
input low_addr_byte[8],
input data_byte[8],
input cntl_byte_read[8],
output read_value[8]
)

{
.clk(clk) {
.rst(rst) {
fsm state = {IDLE, START, ARSTART, RSTART, ADDRESS, MEM_ADDR1, MEM_ADDR2, RADDRESS, RRADDRESS, RMEM_ADDR1, RMEM_ADDR2,DATA, READ,RSTOP,WSTOP,SPIN}; // mcp4725 states write
i2c_controller qwiic(.sda(sda)); // i2c controller
// test_eeprom test_access;
dff newvalue[8];
// value to be written to DAC
dff ack_write;

}

}
// name eeprom_24AA32A
always {

busy = state.q != state.IDLE;

// i2c signals and connections
qwiic.start = 0;
qwiic.stop = 0;
qwiic.write = 0;
ack_write.d = qwiic.ack_write;
scl = qwiic.scl;    
qwiic.read = 0;
qwiic.data_in = 8hxx;  
qwiic.ack_read = 0;

newvalue.d = newvalue.q + 0;  
                      // value to be written to DAC
ack_write.d = ack_write.q + 0;
read_value = 8b00110111;
qwiic.write = write;

case(state.q) {

  state.IDLE:
  
qwiic.start = 0;
qwiic.stop = 0;
qwiic.write = 0;
ack_write.d = qwiic.ack_write;
scl = qwiic.scl;    
qwiic.read = 0;
qwiic.data_in = 8hxx;  
qwiic.ack_read = 0;

newvalue.d = newvalue.q + 0;  
                      // value to be written to DAC
ack_write.d = ack_write.q + 0;
read_value = 8b00110110;
qwiic.write = write;
    // send new dac data
    if(write) {
      // transmit new DAC data over i2c
      state.d = state.START;
      newvalue.d = data_byte;  // capture new DAC data
    } 
    if (read) {
      state.d = state.ARSTART;
    }

  state.START:
    // start i2c controller
    if(!qwiic.busy) {
     state.d = state.ADDRESS;
   qwiic.start = 1;
    }

  state.ADDRESS:
    // if not busy write 1st byte, i2c address, write = 0
   if(!qwiic.busy) {          
      state.d = state.MEM_ADDR1;
      qwiic.write = 1;
    //  qwiic.data_in = 8b10100000;  // address 0xA0 (<< 1)
        qwiic.data_in = cntl_byte_write;  // address 0xA0 (<< 1)
    }    

   state.MEM_ADDR1:
    // if not busy write 2nd byte, low end of byte xxxx0000
  
    if(!qwiic.busy) {
      state.d = state.MEM_ADDR2;
      qwiic.write = 1;
    //  qwiic.data_in = c{8b00000000};
       qwiic.data_in = high_addr_byte;
    } 

  state.MEM_ADDR2:
    // if not busy write 3rd byte, 8 address bits
    if(!qwiic.busy) {
      state.d = state.DATA;
      qwiic.write = 1;
     // qwiic.data_in = 8b00000000;
      qwiic.data_in =  low_addr_byte;
    } 
    
  state.DATA: // write data
   //if not busy write the data byte which is FF 
   if(!qwiic.busy) {
     state.d = state.WSTOP;
     qwiic.write = 1;
    // qwiic.data_in = 8b10101010;
     qwiic.data_in = data_byte;
   } 
    
    state.WSTOP:
    // stop i2c controller
    if(!qwiic.busy) {
      state.d = state.SPIN;           
      qwiic.stop = 1;
    }   

     state.ARSTART:
    // start i2c controller
    if(!qwiic.busy) {
      state.d = state.RADDRESS;
      qwiic.start = 1;
    } 
   
  state.RADDRESS:
    // if not busy write 1st byte, i2c address, write = 0
    if(!qwiic.busy) {          
      state.d = state.RMEM_ADDR1;
      qwiic.write = 1;
      qwiic.data_in = cntl_byte_write;  // address 0xA0 (<< 1)
    }    

  state.RMEM_ADDR1:
    // if not busy write 2nd byte, low end of byte xxxx0000
  
    if(!qwiic.busy) {
      state.d = state.RMEM_ADDR2;
      qwiic.write = 1;
      qwiic.data_in = high_addr_byte;
    } 

  state.RMEM_ADDR2:
    // if not busy write 3rd byte, 8 address bits
    if(!qwiic.busy) {
      state.d = state.RSTART;
      qwiic.write = 1;
      qwiic.data_in = low_addr_byte;
    } 
    
    state.RSTART:
    // start i2c controller
    if(!qwiic.busy) {
      state.d = state.RRADDRESS;
      qwiic.start = 1;
    } 
    
    state.RRADDRESS:
    // if not busy write 1st byte, i2c address, write = 0
    if(!qwiic.busy) {          
      state.d = state.READ;
      qwiic.write = 1;
      qwiic.data_in = cntl_byte_read;  // address 0xA0 (<< 1)  // read bit (8) set to 1
    }    
    
    state.READ: // READ DATA BACK
    // if not busy write the data byte which is FF 
   if(!qwiic.busy) {
     state.d = state.RSTOP;
      qwiic.write = 0;
      qwiic.read = 1;
     //read_value =  8b00110011; //qwiic.data_out;
     read_value = qwiic.data_out;
   } 
    
  state.RSTOP:
    // stop i2c controller
    if(!qwiic.busy) {
      state.d = state.IDLE;           
      qwiic.stop = 1;
    }  
    
    state.SPIN:  // just used for testing
    // stop i2c controller
   
      state.d = state.SPIN;            
} 

}
}
module test_eeprom (

input clk,         // clock
input rst,         // reset
inout sda,         // i2c data
output scl,         // i2c clock

output usb_tx,           // USB->Serial output

input  usb_tx_busy,
output usb_new_tx,
output usb_tx_data[8],
input read_value[8]

) {
.clk(clk) {
.rst(rst) {
fsm state = {IDLE, START, SPIN};
eeprom_24AA32A test(.sda(sda)); // i2c controller

}
 dff delay_timer_enter[32];
 dff max_counter[32];

}

always {

delay_timer_enter.d = 1;
max_counter.d = 1;

//test.usb_tx_busy = 0;
//test.read_value = 0;
test.write = 0;
test.read = 0;

usb_tx = 0;

test.cntl_byte_write = 8b10100000;  // 1010 + 000 + 0  control + address + write mode
test.high_addr_byte  = 8h0;         // xxxx0000  high address
test.low_addr_byte   = 8h0;         // 00000000  low address
test.data_byte       = 8b00110001;  // data to be written which will be a 1
test.cntl_byte_read  = 8b10100001;  // control byte for read

scl = test.scl;

usb_new_tx = 0;
usb_tx_data = 8hxx; 

 
scl = test.scl;

 case (state.q) { // our FSM
  // IDLE: Reset everything and wait for a new byte.
  state.IDLE:
     test.cntl_byte_write = 8b10100000;  // 1010 + 000 + 0  control + address + write mode
     test.high_addr_byte  = 8h0;         // xxxx0000  high address
     test.low_addr_byte   = 8h0;         // 00000000  low address
     test.data_byte       = 8b00110001;  // data to be written which will be a 1
     test.cntl_byte_read  = 8b10100001;  // control byte for read
     
     state.d = state.START; 
 
 state.START:   
       
 delay_timer_enter.d = delay_timer_enter.q + 1; 
 max_counter.d = max_counter.q + 1;
if (delay_timer_enter.q == 1000000000)  // 1,000,000,000
{

 //usb_tx_data = 8hxx;
 test.write = 0; 
 test.cntl_byte_write = 8b10100000;  // 1010 + 000 + 0  control + address + write mode
 test.high_addr_byte  = 8h0;         // xxxx0000  high address
 test.low_addr_byte   = 8h0;         // 00000000  low address
 test.data_byte       = 8b00110001;  // data to be written which will be a 1
 test.cntl_byte_read  = 8b10100001;  // control byte for read
 test.read = 1;
      
  
 if (!usb_tx_busy) 
{
 usb_new_tx = 1;          
 usb_tx_data = test.read_value;  // this is the value read from the eeprom first byt

}
delay_timer_enter.d = 0;
}
if (max_counter.q == 3000000000)
{
state.d = state.IDLE;
max_counter.d = 1;
test.read = 0;
test.write = 0;
}
state.SPIN: // just used for testing
state.d = state.SPIN;

}

Ok, fixed, the issue was this:

read_value = qwiic.data_out; needed to be set in the idle fsm, seems to work fine now, regards,jeff