This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LMK61E2: On-chip EEPROM read-back to get the current (running) clock frequency from the board

Part Number: LMK61E2

Hello,

With your help and support I was able to program the LMK61E2 clock chips on my board to support multiple frequencies and also saving the clock configuration to EEPROM. Now, I am trying to read the EEPROM content from the board, so that whenever the board is power cycled my algorithm should display the current running frequency from the board.

To accomplish this task, I have chosen a simple approach of reading the EEPROM bytes 22, 23 which contains the PLL_NDIV values and compare them with the values from Device registers R25, R26 and display the frequency. I have followed the procedure mentioned in the datasheet (pg-22) for reading of the EEPROM. As mentioned I Wrote EEPROM address byte (22) in R51 and then read R52 in same I2C transaction. However, I am getting a stale value from the EEPROM bytes. Please find below programming sequence which I followed to this task.

//i2c_write_read_immediate(1, 2, 0x51, 0x22, rx_data, 2);  /* supplied values for the function call
/*---------------------------------------------------------------------------*/
static bool i2c_write_read_immediate(uint8_t bcm_no, size_t tx_size, uint8_t reg_no, uint8_t reg_val, uint8_t * reg_data, size_t rx_size)
{
int32_t bytes_written = 0;
int32_t bytes_read = 0;
int32_t result;
uint32_t param; 
size_t rx_size_remaining = rx_size; // variable added LA

/* write the EEPROM register address here, which you intend to read the content, data[1] contains the value */
context.data[0] = reg_no;
context.data[1] = reg_val;

if (context.initialized ) {
if (MQX_OK == _lwsem_wait(&context.sem) ) {

/* write the EEPROM address through i2c driver */
bytes_written = _io_write(context.i2c_fd[bcm_no], context.data, tx_size);
fflush( context.i2c_fd[bcm_no]);
ioctl( context.i2c_fd[bcm_no], IO_IOCTL_FLUSH_OUTPUT, &param);

/* read the next address(reg_no+1) for actual data in same i2c bus*/

context.data[0] = reg_no +1 ; /*R52*/
if (bytes_written == tx_size ) {
ioctl( context.i2c_fd[bcm_no], IO_IOCTL_I2C_REPEATED_START, NULL);
param = rx_size; // should be the total number of bytes to be read LA
ioctl( context.i2c_fd[bcm_no], IO_IOCTL_I2C_SET_RX_REQUEST, &param);

bytes_read = 0;
do {
result = _io_read( context.i2c_fd[bcm_no], &reg_data[bytes_read], rx_size_remaining);
if (result > 0) {
bytes_read += result;
rx_size_remaining -= result; // line added LA
}
} while ((bytes_read < rx_size) && (result >= 0));
}

ioctl( context.i2c_fd[bcm_no], IO_IOCTL_I2C_STOP, NULL); // STOP at end of read operation was missing LA
_lwsem_post(& context.sem);
}
}
return ((rx_size) ==bytes_read); 
}

From the I2C device driver’s control command (IO_IOCTL_I2C_REPEATED_START) I am trying use the same i2c bus to read the value in same transaction. However, my output is always a stale value in reg_data. Could you please look into my methodology and suggest me an approach to solve this problem? or Any other approach to get the running existing on-chip LMK61E2 frequency from the board. I am sure I can read the register content since I have used the read operation while saving EEPROM, not sure what went wrong while doing the write and read in same transaction.

 

Any suggestions/help much appreciated.

  • You can read registers 25 and 26, as they are loaded from EEPROM after a power cycle. Try this and see if you observe the expected values.

    Kind regards,
    Lane
  • Woow, It's working perfectly. I wrote a simple command to read the registers and display the output.

    See below output :

    0000:00:00:17.120 evb> clockset cfp2 2
    Set Clock frequency = 167.380MHz

    Save Eeprom (Y/N) : Y

    Done:

    0000:00:01:41.186 evb> clockget cfp2 
    Reg17 80
    Reg25 0
    Reg26 35
    Done:

    I think, I can complete my task with the read output. Thank you.

    However, Why I am getting stale values by following datasheet instructions of write the address in R51, then Read R52 in same I2c transaction ? Could you please explain briefly.

  • Figuring out exactly why this happens this will require further investigation.
    After saving the settings to EEPROM and power-cycling, are you measuring the desired frequency (167.380MHz) at the output? What frequency do the stale settings correspond to?

    Kind regards,
    Lane

  • Output frequency from the scope showed 167.38 MHz after EEPROM save (also power cycle of the board showed 167.38 MHz), and attaching the scope output here. 

    Coming to the stale values that I encountered are 0x22, 0x23 which are nothing but the EEPROM byte values which I have written in the write EEPROM address in R51 step. If I try to do write and read in two separate i2c transactions, I got some random values like 7A, 7B (though this is not supposed to be done by two separate transactions).

    Also You can find the steps/program sequence that I have followed in the same thread above.