ICM-20948 Wake on Motion功能开发全过程(2)

接前一篇文章:ICM-20948 Wake on Motion功能开发全过程(1)

 

准备工作

上一回解析到ICM-20948基础功能代码中的icm20948_configure函数,解析了前两个函数icm20948_create和icm20948_reset。本回继续往下解析。为了便于理解和回顾,再次贴出icm20948_configure函数代码,如下:

static esp_err_t icm20948_configure(icm20948_acce_fs_t acce_fs, icm20948_gyro_fs_t gyro_fs)
{
    esp_err_t ret;
 
    /*
     * One might need to change ICM20948_I2C_ADDRESS to ICM20948_I2C_ADDRESS_1
     * if address pin pulled low (to GND)
     */
    icm20948 = icm20948_create(I2C_NUM_0, ICM20948_I2C_ADDRESS);
    if (!icm20948)
    {
        ESP_LOGE(TAG, "icm20948_create returned NULL");
        return ESP_FAIL;
    }
    ESP_LOGI(TAG, "icm20948_create successfully");
 
    ret = icm20948_reset(icm20948);
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "icm20948_reset failed");
        return ret;
    }
    ESP_LOGI(TAG, "icm20948_reset successfully");
 
    vTaskDelay(10 / portTICK_PERIOD_MS);
 
    ret = icm20948_wakeup(icm20948);
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "icm20948_wakeup failed");
		return ret;
    }
    ESP_LOGI(TAG, "icm20948_wakeup successfully");
 
    ret = icm20948_set_bank(icm20948, 0);
    if (ret != ESP_OK)
       return ret;
 
    uint8_t device_id;
    ret = icm20948_get_deviceid(icm20948, &device_id);
    if (ret != ESP_OK)
        return ret;
    ESP_LOGI(TAG, "0x%02X", device_id);
    if (device_id != ICM20948_WHO_AM_I_VAL)
        return ESP_FAIL;
 
    ret = icm20948_set_gyro_fs(icm20948, gyro_fs);
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "icm20948_set_gyro_fs failed");
        return ESP_FAIL;
    }
    ESP_LOGI(TAG, "icm20948_set_gyro_fs successfully");
 
    ret = icm20948_set_accel_fs(icm20948, accel_fs);
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "icm20948_set_accel_fs failed");
		return ESP_FAIL;
    }
    ESP_LOGI(TAG, "icm20948_set_accel_fs successfully");
 
	return ret;
}

(3)icm20948_wakeup函数

对应代码片段如下:

    ret = icm20948_wakeup(icm20948);
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "icm20948_wakeup failed");
		return ret;
    }
    ESP_LOGI(TAG, "icm20948_wakeup successfully");

icm20948_wakeup函数代码如下:

esp_err_t icm20948_wakeup(icm20948_handle_t sensor)
{
    esp_err_t ret;
    uint8_t tmp;

    ret = icm20948_read(sensor, ICM20948_PWR_MGMT_1, &tmp, 1);
    if (ESP_OK != ret)
    {
        ESP_LOGE(TAG, "icm20948_read failed");
        return ret;
    }

    tmp &= (~BIT6);

    ret = icm20948_write(sensor, ICM20948_PWR_MGMT_1, &tmp, 1);
    if (ESP_OK != ret)
    {
        ESP_LOGE(TAG, "icm20948_write failed");
        return ret;
    }

    return ESP_OK;
}

icm20948_wakeup函数中,先通过icm20948_read函数读取ICM-20948的PWR_MGMT_1寄存器的内容;之后将bit6清零;再写回到ICM-20948的PWR_MGMT_1寄存器中。

PWR_MGMT_1寄存器对应芯片手册中的以下内容:

(4)icm20948_set_bank函数

对应代码片段如下:

    ret = icm20948_set_bank(icm20948, 0);
    if (ret != ESP_OK)
       return ret;

icm20948_set_bank函数代码如下:

esp_err_t icm20948_set_bank(icm20948_handle_t sensor, uint8_t bank)
{
    esp_err_t ret;

    if (bank > 3)
        return ESP_FAIL;

    bank = (bank << 4) & 0x30;

    ret = icm20948_write(sensor, ICM20948_REG_BANK_SEL, &bank, 1);
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "icm20948_write failed");
        return ret;
    }

    return ESP_OK;
}

icm20948_set_bank函数中,直接通过icm20948_write函数向ICM-20948的REG_BANK_SEL寄存器写入bank值,此处bank值为0。

REG_BANK_SEL寄存器对应芯片手册中的以下内容:

ICM-20948一共有4个BANK(BANK0~3),每个BANK中都有REG_BANK_SEL寄存器,值都是0x7F。这样就可以自由地在BANK间进行切换。实际上,icm20948_configure代码是有问题的。因为PWR_MGMT_1是BANK0中的寄存器,应该先选择BANK,后选择寄存器,而不是到这一步才选择BANK。当然,由于芯片复位后默认是选择BANK0,因此虽然并未显式选择BANK0,PWR_MGMT_1寄存器也是能够正常设置的。

(5)icm20948_get_deviceid函数

对应代码片段如下:

    uint8_t device_id;
    ret = icm20948_get_deviceid(icm20948, &device_id);
    if (ret != ESP_OK)
        return ret;
    ESP_LOGI(TAG, "0x%02X", device_id);
    if (device_id != ICM20948_WHO_AM_I_VAL)
        return ESP_FAIL;

icm20948_get_deviceid函数代码如下:

esp_err_t icm20948_get_deviceid(icm20948_handle_t sensor, uint8_t *const deviceid)
{
    return icm20948_read(sensor, ICM20948_WHO_AM_I, deviceid, 1);
}

icm20948_get_deviceid函数通过icm20948_read函数读取ICM-20948的WHO_AM_I寄存器的内容,并作判断。

WHO_AM_I寄存器对应芯片手册中的以下内容:

由手册可知,ICM-20948的device id为0xEA。上边代码中会检测这个值,如果不是0xEA,则返回错误。

 

icm20948_configure函数中的其余内容,下一回继续解析。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值