i2c read three segments error
Posted: Mon Jul 29, 2019 4:10 pm
Hey,
I'm working on an ESP32-WROOM-32D, in which I have a bootloader.
in my bootloader, I do not use OS and I use an i2c.
the write on my i2c is not a problem, but I can not read in three segments.
the command for segments read are the following:
Here is the code for my reading:
reading the first segment works, I read the expected value. but for the second, I never receive the I2c_END_DETECT_INT interrupt and it seems that the master sends a STOP when it should not.
After reading segment0, the sda line is not released, and the slave does not send the rest of the data.
what I need to add / correct for the reading to go right?
Thanks for help
I'm working on an ESP32-WROOM-32D, in which I have a bootloader.
in my bootloader, I do not use OS and I use an i2c.
the write on my i2c is not a problem, but I can not read in three segments.
the command for segments read are the following:
- Segment0
- RSTART
- WRITE
- READ
- END
- Segment1
- READ
- READ
- END
- Segment2
- STOP
Here is the code for my reading:
Code: Select all
// Segment 0
p_i2c->rx_cnt = cmd->byte_num > p_i2c->rx_fifo_remain ? p_i2c->rx_fifo_remain : cmd->byte_num;
cmd->byte_num -= p_i2c->rx_cnt;
clear_int_status(i2c_num);
I2C[i2c_num]->command[g_cmd_index_use].byte_num = p_i2c->rx_cnt;
I2C[i2c_num]->command[g_cmd_index_use].ack_val = cmd->ack_val;
I2C[i2c_num]->command[g_cmd_index_use+1].val = 0;
I2C[i2c_num]->command[g_cmd_index_use+1].op_code = I2C_CMD_END;
ESP_LOGI(I2C_TAG, "I2C_STATUS_READ");
p_i2c->status = I2C_STATUS_READ;
ESP_LOGI(I2C_TAG, "begin static start transfert");
I2C[i2c_num]->int_clr.end_detect = 1;
I2C[i2c_num]->int_ena.end_detect = 1;
I2C[i2c_num]->ctr.trans_start = 0;
I2C[i2c_num]->ctr.trans_start = 1;
ets_delay_us(10);
clear_int_status(i2c_num);
ESP_LOGI(I2C_TAG, "rx_cnt %d", p_i2c->rx_cnt);
uint8_t readValue = 0;
uint8_t readIndex = 0;
while (p_i2c->rx_cnt-- > 0) {
readValue = READ_PERI_REG(I2C_DATA_APB_REG(i2c_num));
rx_data[readIndex] = readValue;
readIndex++;
ESP_LOGI(I2C_TAG, "-----------------read value %d----------------", readValue);
}
// Segment 1
i2c_master_read(cmdlink, &rx_data[1], 2, 0x0);
i2c_master_read_byte(cmdlink, &rx_data[3], 0x1);
i2c_master_stop(cmdlink);
cmd = &g_cmd_desc[g_cmd_index_use];
ESP_LOGI(I2C_TAG, "g_cmd_index_use %d, g_cmd_index %d, op_code %d", g_cmd_index_use, g_cmd_index, cmd->op_code );
I2C[i2c_num]->command[g_cmd_index_use].val = 0;
I2C[i2c_num]->command[g_cmd_index_use].ack_en = cmd->ack_en;
I2C[i2c_num]->command[g_cmd_index_use].ack_exp = cmd->ack_exp;
I2C[i2c_num]->command[g_cmd_index_use].ack_val = cmd->ack_val;
I2C[i2c_num]->command[g_cmd_index_use].byte_num = cmd->byte_num;
I2C[i2c_num]->command[g_cmd_index_use].op_code = cmd->op_code;
p_i2c->rx_cnt = cmd->byte_num > p_i2c->rx_fifo_remain ? p_i2c->rx_fifo_remain : cmd->byte_num;
cmd->byte_num -= p_i2c->rx_cnt;
clear_int_status(i2c_num);
I2C[i2c_num]->command[g_cmd_index_use].byte_num = p_i2c->rx_cnt;
I2C[i2c_num]->command[g_cmd_index_use].ack_val = cmd->ack_val;
I2C[i2c_num]->command[g_cmd_index_use+1].val = 0;
I2C[i2c_num]->command[g_cmd_index_use+1].op_code = I2C_CMD_END;
ESP_LOGI(I2C_TAG, "begin static start transfert");
I2C[i2c_num]->int_ena.end_detect = 1;
I2C[i2c_num]->ctr.trans_start = 0;
I2C[i2c_num]->ctr.trans_start = 1;
ets_delay_us(10);
clear_int_status(i2c_num);
ESP_LOGI(I2C_TAG, "rx_cnt %d", p_i2c->rx_cnt);
readValue = 0;
readIndex = 0;
while (p_i2c->rx_cnt-- > 0) {
readValue = READ_PERI_REG(I2C_DATA_APB_REG(i2c_num));
rx_data[readIndex] = readValue;
readIndex++;
ESP_LOGI(I2C_TAG, "-----------------read value %d----------------", readValue);
}
After reading segment0, the sda line is not released, and the slave does not send the rest of the data.
what I need to add / correct for the reading to go right?
Thanks for help