static int es_read_reg(uint8_t reg_add, uint8_t *pData) { uint8_t data; int res = 0; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); res |= i2c_master_start(cmd); res |= i2c_master_write_byte(cmd, ES8388_ADDR, 1 /*ACK_CHECK_EN*/); res |= i2c_master_write_byte(cmd, reg_add, 1 /*ACK_CHECK_EN*/); res |= i2c_master_stop(cmd); res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); cmd = i2c_cmd_link_create(); res |= i2c_master_start(cmd); res |= i2c_master_write_byte(cmd, ES8388_ADDR | 0x01, 1 /*ACK_CHECK_EN*/); res |= i2c_master_read_byte(cmd, &data, 0x01/*NACK_VAL*/); res |= i2c_master_stop(cmd); res |= i2c_master_cmd_begin(0, cmd, 1000 / portTICK_RATE_MS); i2c_cmd_link_delete(cmd); ES_ASSERT(res, "es_read_reg error", -1); *pData = data; return res; }
esp_err_t i2c_master_read(i2c_cmd_handle_t cmd_handle, uint8_t *data, size_t data_len, i2c_ack_type_t ack) { I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG); I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG); I2C_CHECK(ack < I2C_MASTER_ACK_MAX, I2C_ACK_TYPE_ERR_STR, ESP_ERR_INVALID_ARG); I2C_CHECK(data_len > 0, I2C_DATA_LEN_ERR_STR, ESP_ERR_INVALID_ARG); if (ack != I2C_MASTER_LAST_NACK) { return i2c_master_read_static(cmd_handle, data, data_len, ack); } else { if (data_len == 1) { return i2c_master_read_byte(cmd_handle, data, I2C_MASTER_NACK); } else { esp_err_t ret; // first read (data_len - 1) byte data with ACK,than read the end byte with NACK. if ((ret = i2c_master_read_static(cmd_handle, data, data_len - 1, I2C_MASTER_ACK)) != ESP_OK) { return ret; } return i2c_master_read_byte(cmd_handle, data + data_len - 1, I2C_MASTER_NACK); } } }
int i2c_write_read(uint8_t stop, uint8_t slave, uint8_t rsize, uint8_t *rbuf, uint8_t wsize, uint8_t *wbuf) { if (rsize == 0 && wsize == 0) { return ESP_OK; } i2c_cmd_handle_t cmd; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); if (wsize) { i2c_master_write_byte(cmd, ( slave << 1 ) | I2C_MASTER_WRITE, ACK_CHECK); i2c_master_write(cmd, wbuf, wsize, ACK_CHECK); if (!rsize) { i2c_master_stop(cmd); \ esp_err_t ret = i2c_master_cmd_begin(I2C_NUM, cmd, 1000 / portTICK_RATE_MS); \ i2c_cmd_link_delete(cmd); // I2C_FINISH; return ret; } if (stop) { // rsize is nonzero i2c_master_stop(cmd); \ esp_err_t ret = i2c_master_cmd_begin(I2C_NUM, cmd, 1000 / portTICK_RATE_MS); \ i2c_cmd_link_delete(cmd); // I2C_FINISH; if (ret) return -1; cmd = i2c_cmd_link_create(); i2c_master_start(cmd); } else { i2c_master_start(cmd); } i2c_master_write_byte(cmd, ( slave << 1 ) | I2C_MASTER_READ, ACK_CHECK); } else { // rsize must be nonzero because of the initial check at the top i2c_master_write_byte(cmd, ( slave << 1 ) | I2C_MASTER_READ, ACK_CHECK); } if (rsize > 1) { i2c_master_read(cmd, rbuf, rsize - 1, ACK_VAL); } i2c_master_read_byte(cmd, rbuf + rsize - 1, NACK_VAL); I2C_FINISH; return ret; }
void task_hmc5883l(void *ignore) { ESP_LOGD(tag, ">> hmc5883l"); i2c_config_t conf; conf.mode = I2C_MODE_MASTER; conf.sda_io_num = PIN_SDA; conf.scl_io_num = PIN_CLK; conf.sda_pullup_en = GPIO_PULLUP_ENABLE; conf.scl_pullup_en = GPIO_PULLUP_ENABLE; conf.master.clk_speed = 100000; ESP_ERROR_CHECK(i2c_param_config(I2C_NUM_0, &conf)); ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0)); uint8_t data[6]; i2c_cmd_handle_t cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (I2C_ADDRESS << 1) | I2C_MASTER_WRITE, 1); i2c_master_write_byte(cmd, 0x02, 1); // 0x02 = "Mode register" i2c_master_write_byte(cmd, 0x00, 1); // 0x00 = "Continuous-Measurement Mode" i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); //Set value in "Configuration Register B" cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (I2C_ADDRESS << 1) | I2C_MASTER_WRITE, 1); i2c_master_write_byte(cmd, 0x01, 1); // 0x01 = "Configuration Register B" i2c_master_write_byte(cmd, 0x20, 1); // 0x20 = default Gain setting i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); //Set active register to "Identification Register A" cmd = i2c_cmd_link_create(); ESP_ERROR_CHECK(i2c_master_start(cmd)); ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (I2C_ADDRESS << 1) | I2C_MASTER_WRITE, 1)); ESP_ERROR_CHECK(i2c_master_write_byte(cmd, 10, 1)); //10 = 0x0A = "Identification Register A" ESP_ERROR_CHECK(i2c_master_stop(cmd)); ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, cmd, 100/portTICK_PERIOD_MS)); i2c_cmd_link_delete(cmd); //Get data from Identification Register A, B and C cmd = i2c_cmd_link_create(); ESP_ERROR_CHECK(i2c_master_start(cmd)); ESP_ERROR_CHECK(i2c_master_write_byte(cmd, (I2C_ADDRESS << 1) | I2C_MASTER_READ, 1)); i2c_master_read_byte(cmd, data, 0); i2c_master_read_byte(cmd, data+1, 0); i2c_master_read_byte(cmd, data+2, 1); ESP_ERROR_CHECK(i2c_master_stop(cmd)); ESP_ERROR_CHECK(i2c_master_cmd_begin(I2C_NUM_0, cmd, 100/portTICK_PERIOD_MS)); i2c_cmd_link_delete(cmd); while(1) { //Set active registert to "Data Output X MSB Register" cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (I2C_ADDRESS << 1) | I2C_MASTER_WRITE, 1); i2c_master_write_byte(cmd, 0x03, 1); //0x03 = "Data Output X MSB Register" i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); //Read values for X, Y and Z cmd = i2c_cmd_link_create(); i2c_master_start(cmd); i2c_master_write_byte(cmd, (I2C_ADDRESS << 1) | I2C_MASTER_READ, 1); i2c_master_read_byte(cmd, data, 0); //"Data Output X MSB Register" i2c_master_read_byte(cmd, data+1, 0); //"Data Output X LSB Register" i2c_master_read_byte(cmd, data+2, 0); //"Data Output Z MSB Register" i2c_master_read_byte(cmd, data+3, 0); //"Data Output Z LSB Register" i2c_master_read_byte(cmd, data+4, 0); //"Data Output Y MSB Register" i2c_master_read_byte(cmd, data+5, 1); //"Data Output Y LSB Register " i2c_master_stop(cmd); i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000/portTICK_PERIOD_MS); i2c_cmd_link_delete(cmd); short x = data[0] << 8 | data[1]; short z = data[2] << 8 | data[3]; short y = data[4] << 8 | data[5]; int angle = atan2((double)y,(double)x) * (180 / 3.14159265) + 180; // angle in degrees ESP_LOGD(tag, "angle: %d, x: %d, y: %d, z: %d", angle, x, y, z); vTaskDelay(1000/portTICK_PERIOD_MS); } vTaskDelete(NULL); } // task_hmc5883l