cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_SPI_Transmit() API

RS009
Associate III

I observed the data on both MOSI and MISO on logic analyzer, even when I use only one of the HAL_SPI_Transmit() or HAL_SPI_Receive(), why?

1 ACCEPTED SOLUTION

Accepted Solutions

This time only, for fun.

Part 1: chatGPT:

When using the HAL_SPI_Transmit() or HAL_SPI_Receive() functions on the STM32, the MOSI and MISO lines are both active. The MOSI line is used to send data from the STM32 to the slave device, while the MISO line is used to receive data from the slave device. Even if you are only transmitting or receiving data in one direction, the MOSI and MISO lines may still be active as the slave device might be configured to send dummy data on the MISO line. Additionally, some slave devices may require that the MOSI line be driven with a specific value (such as a "0") during idle periods to properly function.

View solution in original post

9 REPLIES 9
gbm
Lead III

Cause this is how SPI works. The transfer always goes in both directions, even if one of the wires is not present. ;)

To receive, master must send data - it may be all zeros, all ones or some random stuff. The master may ignore received data but if there is some data signal from slave to master, the slave is sending something.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
RS009
Associate III

oh ok, got it, I think MISO line/wire comes to picture only when we use SPI_Receive API,

I want to write and read back one slave register how to do that?

e.g., Reg = 0x2C 10 1E, first byte is address and second two bytes are data,

 uint8_t Rx_Data[2];

  uint8_t R44[3] = {0x2C,0x10,0x1E};

 uint8_t Buf[]="Application is Running\n";

 HAL_UART_Transmit(&huart3, Buf, strlen((char *)Buf), 1000);

 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12, GPIO_PIN_SET);

 while (1)

 {

 while(! HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13));//on board user btn

 HAL_Delay(200);

 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12, GPIO_PIN_RESET);

 HAL_SPI_Transmit(&hspi1, R44, 1, 1000);

 HAL_SPI_Transmit(&hspi1, &R44[1], 2, 1000);

 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12, GPIO_PIN_SET);

 strcpy((char *)Buf,"Programming is Done\n");

 HAL_UART_Transmit(&huart3, Buf, strlen((char *)Buf), 1000);

 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12, GPIO_PIN_RESET);

 HAL_SPI_Transmit(&hspi1, R44, 1, 1000);

 HAL_SPI_Receive(&hspi1, Rx_Data, 2, 1000);

 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_12, GPIO_PIN_SET);

 sprintf((char*)Buf,"Data is : 0x%X 0x%X \n",Rx_Data[0],Rx_Data[1]);

 HAL_UART_Transmit(&huart3,Buf, strlen((char *)Buf), 1000);

here is my code, please correct me if I am wrong, @Bold line, in logic analyzer I observed that it transmits 3 bytes, why?

Wijeden RHIMI
ST Employee

Hello @RS009 

Thank you for posting your issue !

  • Could you please provide us a screenshot on which we can see the data In logic analyzer?

Best regards,

Wijeden,

S.Ma
Principal

I think chatGPT can explain SPI and how to generate code example snippets on STM32

Pavel A.
Evangelist III

> I think chatGPT can explain SPI 

LOL. Could you share some example? We've already seen some bot generated posts here even so often.

Once chatGPT answers with formatted code source can be html linked, why not?

This time only, for fun.

Part 1: chatGPT:

When using the HAL_SPI_Transmit() or HAL_SPI_Receive() functions on the STM32, the MOSI and MISO lines are both active. The MOSI line is used to send data from the STM32 to the slave device, while the MISO line is used to receive data from the slave device. Even if you are only transmitting or receiving data in one direction, the MOSI and MISO lines may still be active as the slave device might be configured to send dummy data on the MISO line. Additionally, some slave devices may require that the MOSI line be driven with a specific value (such as a "0") during idle periods to properly function.

chatGPT make code : part2:

Can you make a code example for STM32L496 running at 48 MHz core frequency ?

Sure, here is an example of code for initializing and using the SPI peripheral on an STM32L496 running at 48 MHz core frequency:

#include "stm32l4xx_hal.h"

SPI_HandleTypeDef hspi1;

void MX_SPI1_Init(void) {

  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_256;

  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) {

    // Initialization Error

  }

}

uint8_t tx_data = 0x01;

uint8_t rx_data;

int main(void) {

  // Initialize the system and peripherals

  // ...

  MX_SPI1_Init();

  // Transmit and receive data

  HAL_SPI_TransmitReceive(&hspi1, &tx_data, &rx_data, 1, HAL_MAX_DELAY);

  // Use the received data

  // ...

  return 0;

}

Please note that the above code is a simplified example and it's not including any peripheral clock enabling, interrupt handling, or error checking. It's your responsibility to include those in your final application.

Also, you should check the peripheral clock prescaler value, it's set to 256 which would result in a baudrate of (48 MHz / 256) = 187.5 kHz, you can adjust it to your need

Hmmm