2023-07-28 09:34 PM
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.
2023-07-29 08:32 AM
This spike would lead me to believe the device is trying to set SDO high, but it's being pulled down by something else, perhaps the STM32.
It's also odd how the data and clock lines seem to rest at values other than 0 and 3.3V at various points, which indicate maybe multiple devices are trying to drive those pins.
If you can, I would remove the LIS chip, enable an internal pullup on the data line and verify that it gets pulled high when the LIS chip should be outputting to it, then switch it to a pulldown and verify it goes low. My guess is that test will fail.
2023-08-01 01:11 AM
Hi @Cfaya.1,
I wonder if CS stays low for the whole duration of the communication or not, maybe it is driven high by something else? can you share also that screen?
also, can you confirm you write the 4WSPI bit of registerCFG_REG_C (62h) to set the SPI 3 wire?
the suggestion of TDK seems reasonable to me, investigating the comm lines is the best way to tackle the problem =)
If this answers your question, please, mark this as "best answer", by clicking on the "accept as solution" to help the other users of the community
Niccolò