Random Address Read eeprom M24256

Hi,

I am trying to read and write eeprom M24256.

I have used smart configuration but I am not able to read data in random address read.

Datasheet related eeprom said:

Random Address Read:

A dummy write is performed to load the address into the address counter. Then, without sending STOP condition, the master sends another START condition, and repeats the Device Select Code, with the RW bit set to 1. The memory acknowledges this, and outputs hte contents of the adressed byte. The master must not acknowledge the byte output, and terminates the transfer with stop condition.

Could you indicate to me how can manage this situation ?

Br,

Parents
  • Dear Lucaodex, I investigated that, and here's the result:
    Please follow the below project and test if it works on M24256. 

    - When adding I2C master mode, use RIIC0 


    -In the "Config_RIIC0_user.c" file,  declare an extern volatile _Bool flag, and make the below changes to the file. 

    -Main.c file: 

    /***********************************************************************
    *
    *  FILE        : RX66N_IIC_EEPROM_Interfacing.c
    *  DATE        : 2024-03-28
    *  DESCRIPTION : Main Program
    *
    *  NOTE:THIS IS A TYPICAL EXAMPLE.
    *
    ***********************************************************************/
    #include "r_smc_entry.h"
    
    //Define the chip's address
    #define E1 0 //E1 pin logic
    #define E2 0 //E2 pin logic
    #define E3 0 //E3 pin logic
    #define B7_4_ADDR 0xA //Memory access address
    
    void M24xx_read_byte_random(uint8_t const device_address,uint16_t* const address, uint8_t* byte_buffer);
    void M24xx_write_byte_random(uint8_t const device_address,uint16_t* const address, uint8_t* const byte_data);
    void main(void);
    
    volatile _Bool IIC_transmission_end;//IIC bus busy state indicator
    
    uint8_t rx_buffer[10];
    uint8_t tx_buffer[10] = {0xAA};
    uint16_t memory_address = 0xFF;//An arbitrary address of the memory
    
    void main(void)
    {
    
    	const uint8_t device_address = (B7_4_ADDR<<3 | E3<<2 | E2<<1 |E1);//Calculate and store the address of the chip
    
    	R_Config_RIIC0_Start();//RIIC0 Initialization
    
        while (1) {
    
            M24xx_write_byte_random(device_address,&memory_address,&tx_buffer[0]);//save a byte to corresponding memory address
            R_BSP_SoftwareDelay(10, BSP_DELAY_MILLISECS);
            M24xx_read_byte_random(device_address,&memory_address,rx_buffer);//Fetch a byte from corresponding memory address
            R_BSP_SoftwareDelay(10, BSP_DELAY_MILLISECS);
    
        }
    }
    
    
    /*
     * Function: read a single byte from an arbitrary address
     * inputs: Device's address ,16bit address of the memory to be read,Function pointer to the data buffer
     * output: nothing
    */
    void M24xx_read_byte_random(uint8_t const device_address,uint16_t* const address, uint8_t* byte_buffer){
    
    	//Divide 16bit address into two bytes
    	uint8_t addr[2];
    	addr[0] = (uint8_t) ((*address) >> 8);
    	addr[1] = *address;
    	IIC_transmission_end = 0;//Reset IIC bus free flag
    	R_Config_RIIC0_Master_Send_Without_Stop(device_address,(uint8_t*)addr, 2);//Send address to chip
    	while(IIC_transmission_end == 0);//Wait for the data to be sent
    
    	IIC_transmission_end = 0;//Reset IIC bus free flag
    	R_Config_RIIC0_Master_Receive(device_address, byte_buffer, 1);//Retrieve the byte from the memory
    	while(IIC_transmission_end == 0);//Wait for the bus to be free
    
    }
    
    /*
     * Function: write a single byte on an arbitrary address
     * inputs: Device address ,16bit address of the memory to be written,Function pointer to the data buffer
     * output: nothing
    */
    void M24xx_write_byte_random(uint8_t const device_address,uint16_t* const address, uint8_t* const byte_data){
    
    	//Combine address and data to be send to the IC
    	uint8_t data[3];
    	data[0] = (uint8_t) ((*address) >> 8);
    	data[1] = *address;
    	data[2] = *byte_data;
    
    	R_Config_RIIC0_Master_Send(device_address,(uint8_t*)data, 3);//Send address and corresponding data to the chip
    
    }
    



    Now you probably can communicate with the chip properly. it obeys the Read/Write Sequence provided by the M24256 datasheet. 
    The 0xAA value will be written to the 0xFF address of the chip, then you should be able to retrieve that data with the Random Read function.

    I hope you'll find it useful. don't hesitate to ask for clarification if you need it. 

    Kind regards, 
    Hossien. 

    If this or any other user's response answers your concern, kindly verify the answer. Thank you!

    Renesas Engineering Community Moderator
    https://community.renesas.com/
    https://academy.renesas.com/
    en-support.renesas.com/.../


     

  • Hi,

    I have this configuration for the RX64M, so I have different pin.
    Can I use your suggestion changing the port or it is not possible ?

     

Reply Children
  • Hi,

    I have changed these conf inside:

    void R_Config_RIIC01_Create(void)

    {

    ....

    /* Set SCL0 pin */

    MPC.P30PFS.BYTE = 0x0FU;

    PORT3.PMR.BYTE |= 0x01U;

    /* Set SDA0 pin */

    MPC.P26PFS.BYTE = 0x0FU;

    PORT2.PMR.BYTE |= 0x40U;

    .....

    }

  • Feel free to switch to another channel of RIIC, and make sure you have signal on them when application is running. I used RX66N on RCII0 but there might not be a problem to switch on RX64N RIIC1. eventually try not edit smart code generator codes as much as possible. 

  • Hi,
    I can configure in this way.

    RIIC0

    RIIC2

    So I don't know if I can use your code.

    Let me know if I can use your suggestion.

    I think that in the code while I need to use == 1 and not == 0

    while(IIC_transmission_end == 0);//Wait for the data to be sent

    Br,

  • To use the RIIC0 or RIIC2 unit follow the below steps that are for RX64M series:




    According to that, you can use SCL0/SDA0 or SCL2/SDA2 related pins on your hardware. the GPIO configuration will be set automatically by the smart configurator based on components that you're using. 

    And about the "IIC_transmission_end" it's nothing more than a variable that I've used to indicate the end of transmission both in I2C send and received end interrupts. Please don't change it for now. 

  • Hi,

    I have configured all following your suggestion, I changed 

    /* Set SCL0 pin */

    MPC.P30PFS.BYTE = 0x0FU;

    PORT3.PMR.BYTE |= 0x01U;

    /* Set SDA0 pin */

    MPC.P26PFS.BYTE = 0x0FU;

    PORT2.PMR.BYTE |= 0x40U;

    because I have different port in my RX64M,

    but it doesn't work.

    In my view when I need to write I must use at least 0xA0

    like Device Select and when I read I must use 0xA1.

    Using your code I obtain watchdog restart the micro

  • Dear Lucaodex, are you sure you have I2C signals on your device? It would be great if you could monitor SCL/SDA lines with a logic analyzer or oscilloscope to ensure the device is responding to the IIC interface. 
    Regarding watchdog restart, yes it's because of while(1) loops that I've used for making delay between transmissions and when the device isn't responding CPU hangs there. (So feel free to create a fresh project and don't use Watchdog for testing)

     Regards "0xA0 and 0xA1" device addresses, the R_Config_RIIC0_Master_Send() function works with 7bit addresses, and it automatically changes the LSB based on the Read or Write request. 

    I'm suspicious about your configuration and setup. and make sure you've putten this line " R_Config_RIIC0_Start();//RIIC0 Initialization"  before using other functions. 

  • Hi,

    I have this schema

    I don't use while loop but only one shot operation, so one write and one read

    I have inserted  Start at the begging of main and I checked the Create in R_Systeminit

    void main(void)

    {

    R_Config_SCI0_Start();

    R_Config_SCI3_Start();

    R_Config_RIIC0_Start();//RIIC0 Initialization

    R_Config_SCIF8_Start();

    ....

    I have some doubt about SCL0 and SDA0 configuration, really I don't know it right.

    /* Set SCL0 pin */

    MPC.P30PFS.BYTE = 0x0FU;

    PORT3.PMR.BYTE |= 0x01U;

    /* Set SDA0 pin */

    MPC.P26PFS.BYTE = 0x0FU;

    PORT2.PMR.BYTE |= 0x40U;

  •  
    Unfortunately, it's not possible to use RIIC0 or RIIC2 on your hardware. and it's not predicted by the PCB designer. 

    If you're obligated to use that hardware you need to have a little surgery on your board, to connect either P16/P17 or P12/P13 to your memory I2C bus. or implement the code on SCI. 
    However, I recommend you give the RIIC0 code a try and do the surgery on the board, as it's much more convenient to work with. 

  • Hi,

    I'm sorry about it, do you have any suggestion on how to use SCI1 ?

    I have some problem to comunicare with eeprom.

    Br,

  • Unfortunately, I've some doubts about making a  Restart Condition using the SCI unit.

    As I mentioned earlier, the M24256 that you're using needs two consecutive START conditions to respond to Random address data read. which is known as the Restart condition and can be done with the RIIC unit. 
    But the way the SCI unit behaves is different as it's versatile and supports different types of communications 
    the start and stop conditions should come after each other and we cannot manually adjust it and make a Restart condition (I tried but I couldn't do that even using registers).

    Although we might find a hack to do so, for now, unfortunately, I can't help with it. 

    If this or any other user's response answers your concern, kindly verify the answer. Thank you!

    Renesas Engineering Community Moderator
    https://community.renesas.com/
    https://academy.renesas.com/
    en-support.renesas.com/.../