Skip to main content
RSath.1
Associate II
September 14, 2023
Question

STM32L476 SPI incorrect readings

  • September 14, 2023
  • 5 replies
  • 2819 views

I am trying to communicate with a spectrometer sensor using SPI protocol. With SPI default settings, I am using both arduino and Stm32L476 nucleo boards. (8Bits, MSB First, CPOL Low, CPHA 1 Edge).

I read multiple registers from the sensor using both arduino and STM32 nulceo. Everytime the returned values from sensor using STM32 were half of what arduino received.

For example, Reading register 0x0E using arduino showed "12" but STM32 showed "6",   Reading register 0x1A using arduino showed "84", but STM32 showed "42".

According to sensor datasheet, arduino values were correct.

STM32 Code:

static void MX_SPI1_Init(void)
{

 /* USER CODE BEGIN SPI1_Init 0 */

 /* USER CODE END SPI1_Init 0 */

 /* USER CODE BEGIN SPI1_Init 1 */

 /* USER CODE END SPI1_Init 1 */
 /* SPI1 parameter configuration*/
 hspi1.Instance = SPI1;
 hspi1.Init.Mode = SPI_MODE_MASTER;
 hspi1.Init.Direction = SPI_DIRECTION_2LINES;
 hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
 hspi1.Init.NSS = SPI_NSS_SOFT;
 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi1.Init.CRCPolynomial = 7;
 hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
 hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
 if (HAL_SPI_Init(&hspi1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN SPI1_Init 2 */

 /* USER CODE END SPI1_Init 2 */

}

while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */

	 uint8_t addr = 0x0E;

	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, RESET); //cs0
	 HAL_SPI_Transmit(&hspi1, (uint8_t *) &addr, 1, 100);
	 HAL_SPI_Receive(&hspi1,(uint8_t *) &spi_rec, 2, 100);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, SET); //cs0
	 spi_rec1 = spi_rec[0] * 256 + spi_rec[1];

	 HAL_Delay(2000);

}

 

This topic has been closed for replies.

5 replies

Issamos
Super User
September 14, 2023

Hello @RSath.1 

Can you give as your spectrometer reference. Also the Arduino code will be helpful too.

Best regards.

II

RSath.1
RSath.1Author
Associate II
September 14, 2023

Spectrometer - https://ibsen.com/disb-spectrometer-electronics-fast-timing/

 digitalWrite(CS0, LOW);
 byte byte0 = SPI.transfer(0x0E); //Send command to read reg 3.
 unsigned int byte1 = SPI.transfer(0x00); //MSB byte returned from DISB
 unsigned int byte2 = SPI.transfer(0x00); //LSB byte returned from DISB
 
 uint16_t decivalue = byte1 * 256 + byte2;
 Serial.println(decivalue); //Print value to serial port
 digitalWrite(CS0, HIGH); //Set CS0 high again
TDK
September 14, 2023

 

Prior to setting CS low for the first time, send a dummy transaction to initialize the SPI pins:

uint8_t dummy = 0;
HAL_SPI_Transmit(&hspi1, (uint8_t *) &dummy, 1, 100);

SPI_CLK is floating until the first HAL_SPI_Transmit which causes the extra bit.

"If you feel a post has answered your question, please click ""Accept as Solution""."
RSath.1
RSath.1Author
Associate II
September 14, 2023
 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */

	 uint8_t addr = 0x00;
	 HAL_SPI_Transmit(&hspi1, (uint8_t *) &addr, 1, 100);
	 delay_us(100);

	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, RESET); //cs0
	 addr = 0x0E;
	 HAL_SPI_Transmit(&hspi1, (uint8_t *) &addr, 1, 100);
	 HAL_SPI_Receive(&hspi1,(uint8_t *) &spi_rec, 2, 100);
	 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, SET); //cs0
	 spi_rec1 = spi_rec[0] * 256 + spi_rec[1];

	 HAL_Delay(2000);

 }

I tried it, it's still the same issue.

Garnett.Robert
Senior III
September 21, 2023

Hi,

I'm clutching at straws here, but I did some work about seven years ago using SPI on a H7 MCU, and I was having similar problems. It turned out the code for HAL driver SPI that selected the data frame format was incorrect. I hacked it to get it to work. Step through the drivers and just check they are doing the framing correctly.

As I recall the driver specified a data length, but it didn't say whether the length referred to bytes or frames.

Sorry I can't give you more info as I can't even remember what the project was.

Once I fixed the driver it worked seamlessly.

Regards

Rob