Reading bad data from LIS2MDL using 3-wire SPI
Sensor: LI2MDL
MCU: STML072
I am trying to read the who_am_I register (register 0xAF) with the 3-wire SPI setup, but it is returning the wrong data.
Below is a screenshot of the transmission and the return from the LIS2MDL. The transmission's first bit is SET to indicate that it is a READ operation. The return data should be 0x40, however, the first byte is 0x00, and then comes a second byte of data.

Here's the code to read the data:
nBytesToRead == 1
uint8_t Sensor_IO_Read( void *handle, uint8_t ReadAddr, uint8_t *pBuffer, uint16_t nBytesToRead )
{
//NSS = 0;
HW_GPIO_Write( MAGNETOMETER_NSS_PORT, MAGNETOMETER_NSS_PIN, 0 );
uint8_t txData = (ReadAddr | 0x80); // Need to set first bit high for reading
HAL_StatusTypeDef status = HAL_SPI_Transmit( &hspi2, &txData, 1, HAL_MAX_DELAY);
if (status != HAL_OK)
{
PRINTF("SPI read transmit failed status: %d\n", status);
return 1;
}
status = HAL_SPI_Receive( &hspi2, pBuffer, nBytesToRead, HAL_MAX_DELAY);
if (status != HAL_OK)
{
PRINTF("SPI read receive status: %d\n", status);
return 1;
}
//NSS = 1;
HW_GPIO_Write( MAGNETOMETER_NSS_PORT, MAGNETOMETER_NSS_PIN, 1 );
return 0;
}
The SPI settings init config is below:
hspi2.Instance = SPI2;
hspi2.Init.BaudRatePrescaler = SpiFrequency( 1000000 );
hspi2.Init.Direction = SPI_DIRECTION_1LINE; // SPI 3 wire for LI2MDL
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.NSS = SPI_NSS_SOFT; //Hardware
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
I've tried everything I can think of but cannot figure it out. I looked at other registers too, and found that they were also wrong.
When I switch on I2C instead of SPI, everything works fine. I'm trying to use SPI for power savings and speed.
