2025-05-23 4:51 AM
I’m working with a LIS2MDL magnetometer sensor connected to an STM32F407VTG6 microcontroller running FreeRTOS. The sensor communicates over the SPI3 interface, and is configured to operate in SPI Mode 0 (CPOL=0, CPHA=0). The chip select (CS) pin is initialized to HIGH at startup using STM32CubeIDE.
I’ve also attached the wiring diagram and SPI configuration settings from STM32CubeIDE for reference.
In my FreeRTOS task, I enable SPI 4-wire mode, and I’m able to read the WHO_AM_I register successfully—it returns 0x40, confirming that SPI communication over SPI3 is working correctly.
However, the DRDY (Data Ready) flag never goes high, so the sensor doesn't indicate that data is available. When I bypass the DRDY check and try reading the magnetic field values directly, I get invalid data:
X = -1, Y = -1, Z = -1.
This makes me think there may be an issue with the sensor configuration or the data reading process, but I haven’t been able to identify the root cause.
Any help in troubleshooting this would be greatly appreciated.
static int32_t lis2mdl_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len)
{
reg |= 0x40;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);
HAL_SPI_Transmit(handle, ®, 1, HAL_MAX_DELAY);
HAL_SPI_Transmit(handle, (uint8_t *)bufp, len, HAL_MAX_DELAY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
return 0;
}
static int32_t lis2mdl_read(void *handle, uint8_t reg, uint8_t *bufp, uint16_t len)
{
reg |= 0xC0;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET);
HAL_SPI_Transmit(handle, ®, 1, HAL_MAX_DELAY);
HAL_SPI_Receive(handle, bufp, len, HAL_MAX_DELAY);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET);
return 0;
}
void StartLIS2MDLTask(void *argument)
{
stmdev_ctx_t dev_ctx = {
.write_reg = lis2mdl_write,
.read_reg = lis2mdl_read,
.mdelay = platform_delay,
.handle = &hspi3
};
uint8_t whoamI = 0, rst = 0;
int16_t mag_raw[3], temp_raw;
float mag_mG[3], temp_degC;
char buf[128];
// SPI 4-wire aktif et
platform_delay(50);
lis2mdl_spi_mode_set(&dev_ctx, LIS2MDL_SPI_4_WIRE);
platform_delay(50);
// WHO_AM_I kontrol
lis2mdl_device_id_get(&dev_ctx, &whoamI);
snprintf(buf, sizeof(buf), ">> LIS2MDL WHO_AM_I = 0x%02X\r\n", whoamI);
tx_com(buf);
if (whoamI != LIS2MDL_ID) {
tx_com(">> LIS2MDL init FAILED\r\n");
HandleError(ERROR_LIS2_INIT_FAIL, "LIS2Task");
}
tx_com(">> LIS2MDL init OK (SPI 4-wire)\r\n");
// Reset + yapılandırma
lis2mdl_reset_set(&dev_ctx, PROPERTY_ENABLE);
do { lis2mdl_reset_get(&dev_ctx, &rst); } while (rst);
platform_delay(10);
lis2mdl_block_data_update_set(&dev_ctx, PROPERTY_ENABLE);
lis2mdl_data_rate_set(&dev_ctx, LIS2MDL_ODR_100Hz);
lis2mdl_set_rst_mode_set(&dev_ctx, LIS2MDL_SET_SENS_ODR_DIV_63 );
lis2mdl_offset_temp_comp_set(&dev_ctx, PROPERTY_ENABLE);
lis2mdl_operating_mode_set(&dev_ctx, LIS2MDL_CONTINUOUS_MODE);
lis2mdl_drdy_on_pin_set(&dev_ctx, PROPERTY_ENABLE);
osEventFlagsSet(eventGroupHandle, INIT_FLAG_LIS2);
const TickType_t period = pdMS_TO_TICKS(10);
TickType_t lastWake = xTaskGetTickCount();
for (;;)
{
uint8_t drdy = 0;
lis2mdl_mag_data_ready_get(&dev_ctx, &drdy);
snprintf(buf, sizeof(buf), "DRDY = %d\r\n", drdy);
tx_com(buf);
if (drdy)
{
lis2mdl_magnetic_raw_get(&dev_ctx, mag_raw);
for (int i = 0; i < 3; ++i)
mag_mG[i] = lis2mdl_from_lsb_to_mgauss(mag_raw[i]);
lis2mdl_temperature_raw_get(&dev_ctx, &temp_raw);
temp_degC = lis2mdl_from_lsb_to_celsius(temp_raw);
snprintf(buf, sizeof(buf), "[LIS2MDL] X=%.1f Y=%.1f Z=%.1f mG | T=%.2f °C\r\n",
mag_mG[0], mag_mG[1], mag_mG[2], temp_degC);
tx_com(buf);
}
vTaskDelayUntil(&lastWake, period);
}
}
2025-05-23 11:44 AM
I have a same problem, Is here anyone who solving this problem, I need a solution for this problem.