Using the sensor hub mode of lsm6dsl to drive lis2mdl output data unchanged
[Copy link]
I configured LIS2MDL according to the magnet calibration example in "an5040-LSM6DSL: Always-On 3D Accelerometer and 3D Gyroscope.pdf" and tried to read three sets of data from the three registers OUT_MAG_RAW_X_L, SENSORHUB1_REG, and SENSORHUB13_REG, but the actual output did not change. It did not change even when I shook a magnet over the sensor. Can you help me figure out what's going on?
I have tried to drive according to the official driver of lsm6dsl. The code is as follows
int32_t LSM6DSL_SensorHub_Init(void)
{
// 1. 将 80h 写入 FUNC_CFG_ACCESS // 使能对嵌入功能寄存器的访问(A 区)
// 2. 将 3Ch 写入 SLV0_ADD // LIS2MDL 从设备地址 = 0011110b
// 使能写操作(rw_0=0)
// 3. 将 60h 写入 SLV0_SUBADD // 60h 为待写入的 LIS2MDL 寄存器
// 4. 将 8Ch 写入 DATAWRITE_SRC_MODE_SUB_SLV0 // 8Ch 为写入到 LIS2MDL 的寄存器 60h 的值
// 以将其配置为 Continue 模式,
// ODR = 100 Hz,温度补偿使能
uint8_t w_data = 0;
lsm6dsl_sh_cfg_write_t sh_cfg_write;
sh_cfg_write.slv0_add = 0x3C;
sh_cfg_write.slv0_subadd = 0x60;
sh_cfg_write.slv0_data = 0x8C;
if (lsm6dsl_sh_cfg_write(&sh_cfg_write) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 5. 将 10h 写入 SLAVE0_CONFIG // 将 Aux_sens_on 位设置为不等于 00b
if (lsm6dsl_sh_num_of_dev_connected_set(LSM6DSL_SLV_0_1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 6. 将 20h 写入 SLAVE1_CONFIG // 使能 write_once 位
// 7. 将 00h 写入 FUNC_CFG_ACCESS // 禁用对嵌入功能寄存器的访问(A 区)
if (lsm6dsl_sh_write_mode_set(LSM6DSL_ONLY_FIRST_CYCLE) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 8. 将 04h 写入 CTRL10_C // 使能嵌入功能
if (lsm6dsl_func_en_set(1) != LSM6DSL_OK) // lsm6dsl_func_en_set lsm6dsl_pedo_sens_set
{
return LSM6DSL_ERROR;
}
// 9. 将 09h 写入 MASTER_CONFIG // 使能 SDx/SCx 线上的内部上拉
// 传感器集合(sensor hub)触发信号为 XL 数据准备就绪
// 使能辅助 I2C 主线
if (lsm6dsl_sh_pin_mode_set(LSM6DSL_INTERNAL_PULL_UP) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
if (lsm6dsl_sh_master_set(1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 10. 将 80h 写入 CTRL1_XL // 开启加速度计(以获取触发信号)
if (lsm6dsl_xl_data_rate_set(LSM6DSL_XL_ODR_1k66Hz) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
lsm6dsl_func_src1_t func_src1 = {0};
func_src1.sensorhub_end_op = 0;
do
{
// 11. 读取 FUNC_SRC1 // 等待传感器集合通信结束
// 12. 如果 SENSORHUB_END_OP = 0,转到 9
if (lsm6dsl_read_reg(LSM6DSL_FUNC_SRC1, (uint8_t *)&func_src1, 1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
} while (func_src1.sensorhub_end_op == 0);
// 13. 将 00h 写入 CTRL10_C // 禁用嵌入功能
w_data = 0;
if (lsm6dsl_write_reg(LSM6DSL_CTRL10_C, &w_data, 1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 14. 将 00h 写入 MASTER_CONFIG // 禁用辅助 I2C 主线
if (lsm6dsl_write_reg(LSM6DSL_MASTER_CONFIG, &w_data, 1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 15. 将 00h 写入 CTRL1_XL // 关闭加速度计
if (lsm6dsl_write_reg(LSM6DSL_CTRL1_XL, &w_data, 1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 16. 将 80h 写入 FUNC_CFG_ACCESS // 使能对嵌入功能寄存器的访问(A 区)
// 使能读操作(rw_0=1)
// 18. 将 68h 写入 SLV0_SUBADD // 68h 为待读取的第一个 LIS2MDL 输出寄存器
// 19. 将 06h 写入 SLAVE0_CONFIG // 无抽取
// // 连接了 1 个外部传感器
// // 读取的寄存器数 = 6
if (lsm6dsl_mem_bank_set(LSM6DSL_BANK_A) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
w_data = 0x3D;
if (lsm6dsl_write_reg(LSM6DSL_SLV0_ADD, &w_data, 1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
w_data = 0x68;
if (lsm6dsl_write_reg(LSM6DSL_SLV0_SUBADD, &w_data, 1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
w_data = 0x06;
if (lsm6dsl_write_reg(LSM6DSL_SLAVE0_CONFIG, &w_data, 1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 20. 将 FFh 写入 MAG_OFFX_H // X 偏移值初始化
// 21. 将 20h 写入 MAG_OFFX_L // X 偏移值初始化
// 22. 将 00h 写入 MAG_OFFY_H // Y 偏移值初始化
// 23. 将 54h 写入 MAG_OFFY_L // Y 偏移值初始化
// 24. 将 FFh 写入 MAG_OFFZ_H // Z 偏移值初始化
// 25. 将 B4h 写入 MAG_OFFZ_L // Z 偏移值初始化
// 26. 将 0Ah 写入 MAG_SI_XX // XX 软磁参数
// 27. 将 01h 写入 MAG_SI_XY // XY 软磁参数
// 28. 将 00h 写入 MAG_SI_XZ // XZ 软磁参数
// 29. 将 01h 写入 MAG_SI_YX // YX 软磁参数
// 30. 将 08h 写入 MAG_SI_YY // YY 软磁参数
// 31. 将 81h 写入 MAG_SI_YZ // YZ 软磁参数
// 32. 将 00h 写入 MAG_SI_ZX // ZX 软磁参数
// 33. 将 81h 写入 MAG_SI_ZY // ZY 软磁参数
// 34. 将 0Ah 写入 MAG_SI_ZZ // ZZ 软磁参数
// 35. 将 00h 写入 FUNC_CFG_ACCESS // 禁用对嵌入功能寄存器的访问(A 区)
uint8_t mag_off[6] = {0x20, 0xFF, 0x54, 0x00, 0xB4, 0xFF};
uint8_t mag_si[9] = {0x0A, 0x01, 0x00, 0x01, 0x08, 0x81, 0x00, 0x81, 0x0A};
if (lsm6dsl_write_reg(LSM6DSL_MAG_OFFX_H, mag_off, 6) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
if (lsm6dsl_write_reg(LSM6DSL_MAG_SI_XX, mag_si, 9) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
if (lsm6dsl_mem_bank_set(LSM6DSL_USER_BANK) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 36. 将 04h 写入 CTRL10_C // 使能嵌入功能
if (lsm6dsl_func_en_set(1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 37. 将 0Bh 写入 MASTER_CONFIG // 使能 SDx/SCx 线上的内部上拉
// 传感器集合(sensor hub)触发信号为 XL 数据准备就绪
// 使能硬磁校准
// 使能辅助 I2C 主线
w_data = 0x0B;
if (lsm6dsl_write_reg(LSM6DSL_MASTER_CONFIG, &w_data, 1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 38. 将 04h 写入 CTRL9_XL // 使能软磁校准
w_data = 0x04;
if (lsm6dsl_write_reg(LSM6DSL_CTRL9_XL, &w_data, 1) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
// 39. 将 80h 写入 CTRL1_XL // 开启加速度计(以获取触发信号)
if (lsm6dsl_xl_data_rate_set(LSM6DSL_XL_ODR_1k66Hz) != LSM6DSL_OK)
{
return LSM6DSL_ERROR;
}
return LSM6DSL_OK;
}
The second method uses the read and write register driver of lsm6dsl
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] Configure Demo
* @param None
* @retval COMPONENT_OK
* @retval COMPONENT_ERROR
*/
uint8_t Demo_Config(void)
{
uint8_t writeData = 0x80;
lsm6dsl_func_src1_t readData = {0};
//1.使能对嵌入功能寄存器的访问(A 区)
lsm6dsl_write_reg(LSM6DSL_FUNC_CFG_ACCESS, &writeData, 1);
//2.LIS2MDL 从设备地址 = 0011110b
writeData = 0x3cU;
lsm6dsl_write_reg(LSM6DSL_SLV0_ADD, &writeData, 1);
//3.60h 为待写入的 LIS2MDL 寄存器
writeData = 0x60;
lsm6dsl_write_reg(LSM6DSL_SLV0_SUBADD, &writeData, 1);
//4. 8Ch 为写入到 LIS2MDL 的寄存器 60h 的值, Continue 模式 ODR = 100 Hz
writeData = 0x8c;
lsm6dsl_write_reg(LSM6DSL_DATAWRITE_SRC_MODE_SUB_SLV0, &writeData, 1);
//5.将 Aux_sens_on 位设置为不等于 00b
writeData = 0x10;
lsm6dsl_write_reg(LSM6DSL_SLAVE0_CONFIG, &writeData, 1);
//6.使能 write_once 位
writeData = 0x20;
lsm6dsl_write_reg(LSM6DSL_SLAVE1_CONFIG, &writeData, 1);
//7.禁用对嵌入功能寄存器的访问(A 区)
writeData = 0x00;
lsm6dsl_write_reg(LSM6DSL_FUNC_CFG_ACCESS, &writeData, 1);
//8.使能嵌入功能
writeData = 0x04;
lsm6dsl_write_reg(LSM6DSL_CTRL10_C, &writeData, 1);
do{
//9.使能 SDx/SCx 线上的内部上拉 传感器集合(sensor hub)触发信号为 XL 数据准备就绪
writeData = 0x09;
lsm6dsl_write_reg(LSM6DSL_MASTER_CONFIG, &writeData, 1);
//10.开启加速度计(以获取触发信号)
writeData = 0x80;
lsm6dsl_write_reg(LSM6DSL_CTRL1_XL, &writeData, 1);
//11.等待传感器集合通信结束
//12.SENSORHUB_END_OP = 0,转到 9
lsm6dsl_read_reg(LSM6DSL_FUNC_SRC1, (uint8_t *)&readData, 1);
} while(!readData.sensorhub_end_op);
//13.禁用嵌入功能
writeData = 0x00;
lsm6dsl_write_reg(LSM6DSL_CTRL10_C, &writeData, 1);
//14.禁用辅助 I2C 主线
writeData = 0x00;
lsm6dsl_write_reg(LSM6DSL_MASTER_CONFIG, &writeData, 1);
//15.关闭加速度计
writeData = 0x00;
lsm6dsl_write_reg(LSM6DSL_CTRL1_XL, &writeData, 1);
//16.使能对嵌入功能寄存器的访问(A 区)
writeData = 0x80;
lsm6dsl_write_reg(LSM6DSL_FUNC_CFG_ACCESS, &writeData, 1);
//17.LIS2MDL 从设备地址 = 0011110b
writeData = 0x3dU;
lsm6dsl_write_reg(LSM6DSL_SLV0_ADD, &writeData, 1);
//18. 68h 为待读取的第一个 LIS2MDL 输出寄存器
writeData = 0x68;
lsm6dsl_write_reg(LSM6DSL_SLV0_SUBADD, &writeData, 1);
//19. 无抽取;连接了 1 个外部传感器
writeData = 0x06;
lsm6dsl_write_reg(LSM6DSL_SLAVE0_CONFIG, &writeData, 1);
//20~34
uint8_t mag_off[6] = {0x20, 0xFF, 0x54, 0x00, 0xB4, 0xFF};
uint8_t mag_si[9] = {0x0A, 0x01, 0x00, 0x01, 0x08, 0x81, 0x00, 0x81, 0x0A};
lsm6dsl_write_reg(LSM6DSL_MAG_OFFX_L, mag_off, 6);
lsm6dsl_write_reg(LSM6DSL_MAG_SI_XX, mag_si, 9);
//35.禁用对嵌入功能寄存器的访问(A 区)
writeData = 0x00;
lsm6dsl_write_reg(LSM6DSL_FUNC_CFG_ACCESS, &writeData, 1);
//36.使能嵌入功能
writeData = 0x04;
lsm6dsl_write_reg(LSM6DSL_CTRL10_C, &writeData, 1);
//37.使能 SDx/SCx 线上的内部上拉
writeData = 0x0b;
lsm6dsl_write_reg(LSM6DSL_MASTER_CONFIG, &writeData, 1);
//38.使能软磁校准
writeData = 0x04;
lsm6dsl_write_reg(LSM6DSL_CTRL9_XL, &writeData, 1);
//39.开启加速度计(以获取触发信号)
writeData = 0x80;
lsm6dsl_write_reg(LSM6DSL_CTRL1_XL, &writeData, 1);
}
And read the register, but the value obtained has not changed
lsm6dsl_read_reg(LSM6DSL_SENSORHUB13_REG, caliMag, 6);
lsm6dsl_read_reg(LSM6DSL_SENSORHUB1_REG, cali2Mag, 6);
lsm6dsl_read_reg(LSM6DSL_OUT_MAG_RAW_X_L, rawMag, 6);
I also refer to the official "STM32CubeExpansion_MEMS-XT1_V4.4.0" example, but it doesn't seem to help my project.
|