2023-10-20 01:26 PM - edited 2023-10-20 01:56 PM
I'm trying to get an accelerometer connected to my Nucleo-g070RB. I've got the STEVAL-MKI164V1 board with a LIS2HH12 on it.
The problem I have is I always get either zero of 0xFF when try to read the device ID (WhoAmI) which is not correct.
The 2 boards are wired up as:
+3.3V ------- Vdd
+3.3V ------- Vdd_IO
Ground ------ Ground
PA6 --------- JP2(22) SDO
PA7 --------- JP2(21) SDA/SDI/SDO
PA1 --------- JP2(20) SCL/SPC
PA4 --------- JP2(19) CS
From my .ioc file I've configured things as follows
Data Size : 8bits
First Bit: MSB First
CPOL: High
CPHA: 2 Edge
Also I've configured PA4 as a digital output to use for CS
I found another post in this forum indicating these settings are correct LIS2HH12 does not respond on SPI
Initially I thought that CPHA should have been on 1 Edge. With this setting change I get FF every time instead of the first few samples.
The GPIO settings from the .ioc file look like this
I've included the files lis2hh12_reg.c and lis2hh12_reg.h from the github repo STMicroelectronics/lis2hh12-pid
I used the examples in the github repo STMicroelectronics/STMems_Standard_C_drivers/lis2hh12_STdC/examples/lis2hh12_self_test.c as a guide for how to set things up.
The platform read and write functions look like (note that the HAL_Delay(1) in the platfrom_read is actually just something I added as a test but I had a version without the delay and it didn't seem to make any difference)
stmdev_ctx_t dev_ctx;
int32_t platform_write(void *handle, uint8_t Reg, const uint8_t *Bufp, uint16_t len){
HAL_StatusTypeDef result = 0;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
result |= HAL_SPI_Transmit(handle, &Reg, 1, 1000);
result |= HAL_SPI_Transmit(handle, (uint8_t*) Bufp, len, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
return result;
}
int32_t platform_read(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len){
HAL_StatusTypeDef result = 0;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
HAL_Delay(1);
result |= HAL_SPI_Transmit(handle, &Reg, 1, 1000);
result |= HAL_SPI_Receive(handle, Bufp, len, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
return result;
}
Then in my main I've added
uint8_t whoamI;
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.handle = &hspi1;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(1000);
//ReadRegister(WHO_AM_I,rxData);
lis2hh12_dev_id_get(&dev_ctx, &whoamI);
printf("%2X\n\r",whoamI);
}
/* USER CODE END 3 */
When I run this code I get output that looks like this in my serial log
FF
FF
0
0
0
0
0
0
0
I've tried a variety of different prescalers to slow down the baud rate but that has not helped.
I've also tried an alternate approach where instead of using the code from the lis2hh12-pid github page I do something like this instead. I tried a variety of permutations of this function with no luck.
HAL_StatusTypeDef ReadRegister(uint8_t addr, uint8_t *byte)
{
HAL_StatusTypeDef hal_status;
uint8_t tx_data[2];
uint8_t rx_data[2];
tx_data[0] = addr | 0x80; // read operation
tx_data[1] = 0; // dummy byte for response
rx_data[0] = 0;
rx_data[1] = 0;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
HAL_Delay(1);
hal_status = HAL_SPI_Transmit(&hspi1, tx_data, 2, 1000);
hal_status = HAL_SPI_Receive(&hspi1, rx_data, 2, 1000);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
if (hal_status == HAL_OK)
{
*byte = rx_data[1]; // response is in the second byte
printf("%2X,%2X\n\r",rx_data[0],rx_data[1]);
} else {
printf("hal_status is HAL_NG\n\r");
}
return hal_status;
}
I don't have a logic analyzer handy but I have tested my CS line with a multimeter and some test code to set that low and high on 1 second intervals and it seems to be working correctly.
I've tried putting in little delays as well as just tying CS to ground with no luck.
I've also tried a version where instead of using the lis2hh12_reg files from the github repo. I included the software component
for the LIS2DH12
And set up my platform read and writes the same as the code sample I provided. That did not produce different results.
I've also tried a version where I connect CS to PB0 and select Hardware NSS Output Signal
Which gives me SPI GPIO configuration that looks like this
In this case I removed the code from my platform read/write to pull CS low before communicating with it. When I did this I get 0xFF every time.
I've been using these documents as a reference DM00096789.pdf, STEVAL-MKI164V1 & Nucleo-64 boards
If anyone has any idea what I can do to get the SPI connection to the sensor working correctly I would greatly appreciate it.
Thank You
2023-10-23 06:51 AM
Hi @marchold ,
The connections are correct, but in NUCLEO-G070RB PA2 (SPI1MOSI) is connected to UART2_TX. this pin is connected to STLINK section. Could you verify it?
If this helps you, please mark my answer as "Best Answer" by clicking on the "Accept as Solution" button, this can be helpful for Community users to find this solution faster.
2023-10-23 01:23 PM - edited 2023-10-23 01:27 PM
Thank you for your reply.
I don't think the PA2 which is connected to the UART2_TX was related to the problem since MOSI in this case is PA7.
I believe the problem was related to the platform read code needed to set the MSB to 1. Adding Reg |= 80 allowed me to get the correct device ID.
int32_t platform_read(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len){
HAL_StatusTypeDef result = 0;
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
Reg |= 0x80;
result |= HAL_SPI_Transmit(handle, &Reg, 1, 1000);
result |= HAL_SPI_Receive(handle, Bufp, len, 1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
return result;
}
I don't think this had anything to do with it but in the latest working version I also modified some settings for the CS GPIO
I ended up getting a logic analyzer and found this post SPI MISO line stays high? to be helpful. That post was indicating that the problem was on the sensor side since everything else looked correct but the MISO line was just stying high and it did not matter if I was even connected to the sensor board. In the documentation in section 6.2.1 it says
bit 0: RW bit. When 0, the data DI(7:0) is written into the device. When 1, the data DO(7:0) from the device is read. In latter case, the chip will drive SDO at the start of bit 8.
which tipped me off to the problem.
2023-10-25 04:46 PM - edited 2023-10-25 05:35 PM
The Reg |= 80 was part of the problem but there is still an issue.
Everything is working fine with the logic analyzer connected but as soon as I disconnect the logic analyzer I start to get unpredictable results. I'm able to read the device ID but when I read the accelerometer values I will get random values without the logic analyzer connected.
I was able to resolve this part of the issue by connecting 4.7k resistors from power to all 4 SPI lines.