Hello,
I'm trying to implement a comunication with a I2C device. I have a RA6M4 microcontroller and just one slave device on I2C.
The write operation seems to be good, as far the device has a expected behaviour.
But, in read operation, i can not fulfill the sequence of the device. The sequence is like a I2C read memory:
The point is:
- If I execute the read function (R_IIC_MASTER_Read), the start, device address, read bit, and acknoledge is good, but register address is always 0xFF, like a dummy byte.
- If I execute the write function, (R_IIC_MASTER_Write), the start and device address is good, but it sends always the write bit (0).
So, how can I achieve the correct sequence? No examples found that work it.
Thanks.
Hello David,
Thanks for reaching out Renesas Engineering Community.
First of all I would suggest to you to advise the documentation of the r_iic_master module in FSP.
https://renesas.github.io/fsp/group___i_i_c___m_a_s_t_e_r.html
There is also an example code.
Also let me inform you that the IIC driver in FSP is a non blocking driver, which means that for example if your preform a Write operation
the R_IIC_Write() API will return immediately and you should declare a callback as this one shown below to get notified that your operation is actually completed even though it returns FSP_SUCCESS.
/* Callback function */ void g_i2c_master0_callback(i2c_master_callback_args_t *p_args) { /* TODO: add your own code here */ i2c_event=p_args->event; }
And check the value of the variable i2c_event. And check if it gets one this values below:
In order to find out what is going wrong we would like to have more information from you like your configurations for I2C and some sample code.
However let me attach for you an example for I2C that worked for me for reading an I2C temperature sensor. Notice that the example might be forEK-RA2L1 but nothing changes as far as it concerns the code, only set your own slave address and of course change the configurations for EK-RA6M4 for the I2C stack (pins, channels etc.).
Hope this helps.
Best Regards,
IK
5355.i2c_masterEK_RA2L1.zip
i copied the function readReg, and it's the same. In this function, you perform a write, then you are sending a write bit.
My slave address is 0x30. Then all are going 0's, so bit R/W is W and should be read.
This function return a value (in output variable) that has no sense.
My slave device is a led driver KTD2027. I can do a reset of the device, send a control current value, turn on and off the led1. I can assume I2C is working. Driver is my problem when i want to read.
This is my code that only writes and works:
void pruebasLED() { static bool started = 0; fsp_err_t err; if (!started) { /* Initialize the IIC module */ err = R_IIC_MASTER_Open (g_i2c_master0.p_ctrl, g_i2c_master0.p_cfg); assert(FSP_SUCCESS == err); // Genera 20 clocks para finalizar cualquier transacción iniciada anteriormente. /*for (int i = 0; i < 20; i++) { g_i2c_master0_ctrl.p_reg->ICCR1_b.CLO = 1; while (g_i2c_master0_ctrl.p_reg->ICCR1_b.CLO) { } }*/ // Aseguramos que nosotros no tenemos nada a medias. R_IIC_MASTER_Abort (g_i2c_master0.p_ctrl); started = true; } uint8_t addressToSend = 0x30; err = R_IIC_MASTER_SlaveAddressSet (g_i2c_master0.p_ctrl, addressToSend, I2C_MASTER_ADDR_MODE_7BIT); assert(FSP_SUCCESS == err); //Mandamos Reset i2c_event = 0; uint8_t data[8] = { 0, 7, 0, 0, 0, 0, 0, 0 }; err = R_IIC_MASTER_Write (g_i2c_master0.p_ctrl, data, 2, false); uint32_t timeout = 1000; while ((i2c_event == 0) && timeout--) { R_BSP_SoftwareDelay (1, BSP_DELAY_UNITS_MILLISECONDS); } // Después del reset esperamos un tiempo prudencial. R_BSP_SoftwareDelay (500, BSP_DELAY_UNITS_MILLISECONDS); // limitamos la corriente del led 1 i2c_event = 0; data[0] = 6; data[1] = 20; err = R_IIC_MASTER_Write (g_i2c_master0.p_ctrl, data, 2, false); timeout = 1000; while ((i2c_event == 0) && timeout--) { R_BSP_SoftwareDelay (1, BSP_DELAY_UNITS_MILLISECONDS); } //Encendemos el led 1 i2c_event = 0; data[0] = 4; data[1] = 1; err = R_IIC_MASTER_Write (g_i2c_master0.p_ctrl, data, 2, false); timeout = 1000; while ((i2c_event == 0) && timeout--) { R_BSP_SoftwareDelay (1, BSP_DELAY_UNITS_MILLISECONDS); } //Apagamos el led 1 i2c_event = 0; data[0] = 4; data[1] = 0; err = R_IIC_MASTER_Write (g_i2c_master0.p_ctrl, data, 2, false); timeout = 1000; while ((i2c_event == 0) && timeout--) { R_BSP_SoftwareDelay (1, BSP_DELAY_UNITS_MILLISECONDS); } readReg(0, data); i2c_event = 0; //err = R_IIC_MASTER_Close(g_i2c_master0.p_ctrl); //assert(FSP_SUCCESS == err); } void i2c_callback(i2c_master_callback_args_t *p_args) { i2c_event = p_args->event; }
My configuration is:
Can you confirm that the oscilloscope shows signal that doesn't fit the protocol?
Hi David,
Yes, as far I can understand the red line is the SDA and the blue line the SCL.
I can see from the screenshot you have sent, the start condition and the adress 0x30 but you are right the R/W bit after the address is not set to 1 for read operation.
But is this screenshot from the read operation? Since to read the contents of Reg0 which is 0x00 you first need to write to the slave the adress of the register you want to read.
And also according to the datasheet of the Led driver what are you supposed to read when reading Reg0?
Also have you tried to read the contents of the ICDRR register? And when calling in your code the Read() API what is the value of the i2c_event variable?
Regards,
"But is this screenshot from the read operation?"
Following your example, in your function readReg you make two "steps". First you call R_IIC_MASTER_Write with some parameters and after you call R_IIC_MASTER_Read. The signals are after the first step.
"Since to read the contents of Reg0 which is 0x00 you first need to write to the slave the adress of the register you want to read."
NO. To read I just need to follow what the datasheet says:
White are signals from Renesas microcontroler.
Green are signals from Led Driver.
There is no two step procedure like you say. It's not write the address, then read. Is just all in one. No restart no stops and start again.
Maybe is a tricky way to do the read? Like I want to write you at this address, then stop with no data and make a read because cursor maybe is changed with the aborted writed?
I found on the datasheet of ISL12028 (i worked on it in the past) the behaviour your demo is doing:
In words says:
Random read operations allow the master to access any location in the ISL12028. Prior to issuing the Slave Address Byte with the R/W bit set to zero, the master must first perform a “dummy” write operation.
That's ok for ISL12028, but it's not the way that says my led driver.
Also have you tried to read the contents of the ICDRR register? No, I always supposed that all I need are FSP functions, so no need to know about registers since there is a function for read I2C.
when calling in your code the Read() API what is the value of the i2c_event variable? Always is I2C_MASTER_EVENT_RX_COMPLETE or I2C_MASTER_EVENT_TX_COMPLETE after power on. After first try, i get some errors I think because i never close I2C. In this case i power off the board and then power on and returns to ok. But never reading ok.
If a go to the end, the function returns me always a 0xFF.
The master receive operation will just send the address bits, the read bit and nothing else. From this moment the master is in receive mode and receiving data from the slave.
The read operation on your datasheet cannot be implemented with RA.
To do a read, you first do a write with restart, then do a read. This is exactly what your diagram shows
Dale.