Page 1 of 1

i2c_master_cmd_begin() returns ESP_FAIL

Posted: Tue Jun 29, 2021 11:40 am
by adi_1234
Hello,
i am trying to read time from the rtc - PCF85263ATT, so i start with writing the write-slave-address (0xA2) and the register to start reading from (seconds register 0x1) and i get NACK (as it shows on the oscilloscope). This NACK causes the failure of i2c_master_cmd_begin() with ESP_FAIL error.
scl pin is set to 18, sda is pin 19, i2c_port is I2C_NUM_0.
IMG_20210629_131754.jpg
IMG_20210629_131754.jpg (1.81 MiB) Viewed 3572 times
here is the code:
  1.  
  2. #define PCF85263ATT_SLAVE_REG_WRITE 0xA2
  3. #define PCF85263ATT_SLAVE_REG_READ 0xA3
  4. #define  PCF85263ATT_REG_SECONDS  0x01
  5.  
  6. typedef struct RtcDriver {
  7.     int sda_pin_num;
  8.     int scl_pin_num;
  9.     i2c_port_t i2c_port;
  10. } RtcDriver;
  11.  
  12.  
  13. esp_err_t rtc_driver_init(RtcDriver* rtc_driver) {
  14.     i2c_config_t conf = {
  15.     .mode = I2C_MODE_MASTER,
  16.     .sda_io_num = rtc_driver->sda_pin_num,        
  17.     .sda_pullup_en = GPIO_PULLUP_DISABLE,  //there are pullup resistors in the circuit
  18.     .scl_io_num = rtc_driver->scl_pin_num,        
  19.     .scl_pullup_en = GPIO_PULLUP_DISABLE,  //there are pullup resistors in the circuit
  20.     .master.clk_speed = 400000,  
  21.     };
  22.     esp_err_t err;
  23.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_driver_install(rtc_driver->i2c_port, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0));
  24.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_set_data_mode(rtc_driver->i2c_port, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST));
  25.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_param_config(rtc_driver->i2c_port, &conf));
  26.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_set_timeout(rtc_driver->i2c_port, 9000 / portTICK_RATE_MS));
  27.     return 0;
  28. }
  29.  
  30. esp_err_t rtc_driver_get_time(RtcDriver* rtc_driver, uint8_t* sec, uint8_t* min, uint8_t* hour){
  31.     i2c_cmd_handle_t cmd = NULL;
  32.     cmd = i2c_cmd_link_create();
  33.     if(cmd == NULL) {
  34.         ESP_LOGI(TAG, "i2c_cmd_link_create failed!" );
  35.     }
  36.     uint8_t data[3];  
  37.     data[0] = PCF85263ATT_SLAVE_REG_WRITE;
  38.     data[1] = PCF85263ATT_REG_SECONDS;
  39.     data[2] = PCF85263ATT_SLAVE_REG_READ;
  40.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_start(cmd));
  41.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_byte(cmd, data[0] , ACK_CHECK_DIS)); //slave addr
  42.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write_byte(cmd, data[1], ACK_CHECK_EN)); //start to read from sec rgstr
  43.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_stop(cmd));
  44.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(rtc_driver->i2c_port, cmd, 1000 / portTICK_RATE_MS));
  45.     i2c_cmd_link_delete(cmd);
  46.     vTaskDelay(100 / portTICK_RATE_MS);
  47.     cmd = i2c_cmd_link_create();
  48.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_start(cmd));
  49.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_write(cmd, &data[2], 1, true));
  50.     data[0] = 0;
  51.     data[1] = 0;
  52.     data[2] = 0;
  53.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_read(cmd, &data[0], sizeof(data) ,I2C_MASTER_LAST_NACK));
  54.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_stop(cmd));
  55.     esp_err_t err;
  56.     ESP_ERROR_CHECK_WITHOUT_ABORT(i2c_master_cmd_begin(rtc_driver->i2c_port, cmd, 1000 / portTICK_RATE_MS));
  57.     i2c_cmd_link_delete(cmd);
  58.     return 0;
  59. }
The second call to i2c_master_cmd_begin() returns ESP_ERR_TIMEOUT.
here is the datasheet of the rtc: https://www.nxp.com/docs/en/data-sheet/PCF85263A.pdf

What am i doing wrong?
i really wish to figure out why the rtc won't ack and why do i get ESP_ERR_TIMEOUT on the second call to i2c_master_cmd_begin().

Thank You,
Adi

Re: i2c_master_cmd_begin() returns ESP_FAIL

Posted: Wed Jul 07, 2021 11:01 am
by kalpanavengala
Hi,
I have seen your code, maybe in line 41, the third parameter in the i2c_master_write_byte as ACK_CHECK_EN. If you are disabling the acknowledge check condition if the slave sends the NACK master will not check the condition and it will not enable the I2C_NACK_INTR maybe that is the cause to get the failure.