Skip to main content
Associate III
September 4, 2024
Solved

\0 is added in the front of my message when using HAL_SPI_Receive_DMA()

  • September 4, 2024
  • 7 replies
  • 3620 views

Hello,

I'm commucating two STM32 F4 boards  using SPI

The first board is configured as a Master and used to only transmit data 

 

 

#define message_tx_size 4
uint8_t message_tx[message_tx_size] = "ABCD";
....
int main(void){
	while (1){
		HAL_SPI_Transmit(&hspi1, message_tx, message_tx_size, HAL_MAX_DELAY);
	}
}

 

 

The second board is configured as a Slave and used to only receiver data

 

 

 

//main.c
#define message_rx_size 4
uint8_t message_rx[message_rx_size];

int main(void){
 while (1){
 if ((1 == msgRX)){ //Process the message
			msgRX = 0;
	 } else if (0 == msgRX){
			msgRX = -1;

			memset(&struct_example_data_rx, '\0', size_of_struct_example_data);
			HAL_SPI_Receive_DMA(&hspi1, (uint8_t *)&struct_example_data_rx, size_of_struct_example_data);
	 }

	 HAL_Delay(200);
 }
}

//stm32f4xx_it.c
extern volatile int msgRX;
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
	if(hspi->Instance == hspi1.Instance && -1 == msgRX) {
		 msgRX = 1;
	}
}

 

 

 

The problem is: for the first iteration, I receive the exact data. But after a few itteration, the data I received becomes "\0ABC".

And if I re-run the receiver, without re-runing the transmiter, then I got the same exact result: OK at the begening, but altered after.

Thank you for help

 

 

Best answer by Dreamer3D

Hello, 

It's finnaly some experimental work and ChatGPT who resolve the problem

look bellow at this response that ChatGPT gave me.

Apparently, the circular mode is perfect for continous data transfer 

Screenshot_DMA_MODE_STM32.png

7 replies

Bob S
Super User
September 4, 2024

Is that REALLY your code?  Because your "master" code is in a loop sending those 4 bytes over and over as fast as it can with no (or minimal) delay between each TX call.  Your slave code, on the other hand, has a 200ms delay.  So it will likely start receiving somewhere in the middle of a "packet" from the master, and not even guaranteed to be on a byte boundary.

Are you using a hardware SS signal (slave select)?  You don't show the SPI config code, so I can't tell.  That signal is used to "frame" the data and help ensure the master and slave are synchronized.  If not, you should add that - the slave side can use the hardware SS feature, but (usually) the master needs to use software controlled GPIO as the SS output because the STM32 "master SS" feature usually doesn't do what most people THINK it does (or want it to do).

BarryWhit
Lead
September 4, 2024

@Bob S wrote:

 

[...] because the STM32 "master SS" feature usually doesn't do what most people THINK it does (or want it to do).


This is true for older chips (like STM32F103,  STM32G4), but newer chips (Like STM32U5, and others) have introduced new modes for the NSS signal so I'm not sure this fair warning applies to them. One has to check the RM for any specific chip. Some discussion of this is here.

 

Update:

Dupe: Impossible to receive data in loop using SPI with interupt

"- If someone's post helped resolve your issue, please thank them by clicking ""Accept as Solution"".- Please post an update with details once you've solved your issue. Your experience may help others."
BarryWhit
Lead
September 5, 2024

These kinds of manual delays are often indicators of poor design. Perhaps we could be more helpful if you explain more fully what you're trying to achieve. Whatever that is, synchronizing with hard-coded delays is almost certainly the wrong approach.

"- If someone's post helped resolve your issue, please thank them by clicking ""Accept as Solution"".- Please post an update with details once you've solved your issue. Your experience may help others."
Dreamer3DAuthor
Associate III
September 5, 2024

My only goal is just to use SPI to send data from one board and to receive the exact data on another board. The presence of an '\0' at the begening of the data I received leads to several errors when manipulate the data.  

BarryWhit
Lead
September 5, 2024

Fair enough. What was your intention when you introduced the HAL_Delay(200) line into the receiver's main loop?

"- If someone's post helped resolve your issue, please thank them by clicking ""Accept as Solution"".- Please post an update with details once you've solved your issue. Your experience may help others."
BarryWhit
Lead
September 5, 2024

Is the \0 due to zeros being read on the bus, or maybe the DMA is getting interrupted in some way, and skipping the first byte? Change the memset to 0xff and retest. 

"- If someone's post helped resolve your issue, please thank them by clicking ""Accept as Solution"".- Please post an update with details once you've solved your issue. Your experience may help others."
Dreamer3DAuthor
Associate III
September 5, 2024

I did not change anything on the transmiter, and I change to 0xff the memeset on the receiver. But it still not work. The data is only OK on the first itteration.

I saw something from a forum on community.st.com about clearing the buffer. It migth be that the data from the last iteration is still inside the buffer. And since '\0' is the last character on the buffer, then it is added into the new value of the buffer?

//https://community.st.com/t5/stm32-mcus-products/how-to-clear-internal-spi-tx-buffer-in-slave-mode-after/td-p/366546/page/2 

Dreamer3DAuthor
Associate III
September 19, 2024

Hello,

I already posted my problem a few weeks ago, but it is still not resolved. This is the link to my last post: 

Re: \0 is added in the front of my message when using HAL_SPI_Receive_DMA()

 My goal is to use two STM32F4 boards to transfer data: the first board is configured as Master and only transmit data. And the second borad is configured as Slave and only receive data. I receive the data on the slave board, but the data is altered. an '\0' is added at the begening of the data.

This is an example of the steps on the Debug I see on the slave boad when I send a data ="ABC" of size 5

run 1 on the debug mode: message received = "ABC"

run 2 on the debug mode: message received = "AABC"

run 3 on the debug mode: message received = "\0ABC"

...

run n on the debug mode: message received = "\0ABC"

Master board

 

 

 

int main(void)
{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_ETH_Init();
 MX_USART3_UART_Init();
 MX_USB_OTG_FS_PCD_Init();
 MX_SPI1_Init();
 /* USER CODE BEGIN 2 */
uint8_t message_tx[5] = "ABC";
 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
	 HAL_SPI_Transmit(&hspi1, message_tx, 5, HAL_MAX_DELAY);
	 HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);

	 HAL_Delay(200);
 }
 /* USER CODE END 3 */
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Configure the main internal regulator output voltage
 */
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLM = 4;
 RCC_OscInitStruct.PLL.PLLN = 120;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
 RCC_OscInitStruct.PLL.PLLQ = 5;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
 {
 Error_Handler();
 }
}

/**
 * @brief ETH Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_ETH_Init(void)
{

 /* USER CODE BEGIN ETH_Init 0 */

 /* USER CODE END ETH_Init 0 */

 static uint8_t MACAddr[6];

 /* USER CODE BEGIN ETH_Init 1 */

 /* USER CODE END ETH_Init 1 */
 heth.Instance = ETH;
 MACAddr[0] = 0x00;
 MACAddr[1] = 0x80;
 MACAddr[2] = 0xE1;
 MACAddr[3] = 0x00;
 MACAddr[4] = 0x00;
 MACAddr[5] = 0x00;
 heth.Init.MACAddr = &MACAddr[0];
 heth.Init.MediaInterface = HAL_ETH_RMII_MODE;
 heth.Init.TxDesc = DMATxDscrTab;
 heth.Init.RxDesc = DMARxDscrTab;
 heth.Init.RxBuffLen = 1524;

 /* USER CODE BEGIN MACADDRESS */

 /* USER CODE END MACADDRESS */

 if (HAL_ETH_Init(&heth) != HAL_OK)
 {
 Error_Handler();
 }

 memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
 TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
 TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
 TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
 /* USER CODE BEGIN ETH_Init 2 */

 /* USER CODE END ETH_Init 2 */

}

/**
 * @brief SPI1 Initialization Function
 * @PAram None
 * @retval None
 */
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_32;
 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
 hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi1.Init.CRCPolynomial = 10;
 if (HAL_SPI_Init(&hspi1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN SPI1_Init 2 */

 /* USER CODE END SPI1_Init 2 */

}

/**
 * @brief USART3 Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_USART3_UART_Init(void)
{

 /* USER CODE BEGIN USART3_Init 0 */

 /* USER CODE END USART3_Init 0 */

 /* USER CODE BEGIN USART3_Init 1 */

 /* USER CODE END USART3_Init 1 */
 huart3.Instance = USART3;
 huart3.Init.BaudRate = 115200;
 huart3.Init.WordLength = UART_WORDLENGTH_8B;
 huart3.Init.StopBits = UART_STOPBITS_1;
 huart3.Init.Parity = UART_PARITY_NONE;
 huart3.Init.Mode = UART_MODE_TX_RX;
 huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart3.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_UART_Init(&huart3) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART3_Init 2 */

 /* USER CODE END USART3_Init 2 */

}

/**
 * @brief USB_OTG_FS Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_USB_OTG_FS_PCD_Init(void)
{

 /* USER CODE BEGIN USB_OTG_FS_Init 0 */

 /* USER CODE END USB_OTG_FS_Init 0 */

 /* USER CODE BEGIN USB_OTG_FS_Init 1 */

 /* USER CODE END USB_OTG_FS_Init 1 */
 hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
 hpcd_USB_OTG_FS.Init.dev_endpoints = 4;
 hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
 hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;
 hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
 hpcd_USB_OTG_FS.Init.Sof_enable = ENABLE;
 hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
 hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
 hpcd_USB_OTG_FS.Init.vbus_sensing_enable = ENABLE;
 hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
 if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USB_OTG_FS_Init 2 */

 /* USER CODE END USB_OTG_FS_Init 2 */

}

/**
 * @brief GPIO Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOH_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOG_CLK_ENABLE();

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin : USER_Btn_Pin */
 GPIO_InitStruct.Pin = USER_Btn_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pins : LD1_Pin LD3_Pin LD2_Pin */
 GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin|LD2_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 /*Configure GPIO pin : USB_PowerSwitchOn_Pin */
 GPIO_InitStruct.Pin = USB_PowerSwitchOn_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(USB_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pin : USB_OverCurrent_Pin */
 GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
 * @brief This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
 }
 /* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
 * @brief Reports the name of the source file and the source line number
 * where the assert_param error has occurred.
 * @PAram file: pointer to the source file name
 * @PAram line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
 /* USER CODE BEGIN 6 */
 /* User can add his own implementation to report the file name and line number,
 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

 

Slave board

 

 

 

volatile int msgFromSPI = 0;
int main(void)
{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_ETH_Init();
 MX_USART3_UART_Init();
 MX_USB_OTG_FS_PCD_Init();
 MX_SPI1_Init();
 /* USER CODE BEGIN 2 */
 uint8_t msg_buffer_rx[5];
 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */

	 if (1 == msgFromSPI){ //Process the message
			msgFromSPI = 0;
			HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_7);
	 } else if (0 == msgFromSPI){
			msgFromSPI = -1;
			HAL_SPI_Receive_DMA(&hspi1, msg_buffer_rx, 5);
	 }
 }
 /* USER CODE END 3 */
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Configure the main internal regulator output voltage
 */
 __HAL_RCC_PWR_CLK_ENABLE();
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLM = 4;
 RCC_OscInitStruct.PLL.PLLN = 168;
 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
 RCC_OscInitStruct.PLL.PLLQ = 7;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
 {
 Error_Handler();
 }
}

/**
 * @brief ETH Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_ETH_Init(void)
{

 /* USER CODE BEGIN ETH_Init 0 */

 /* USER CODE END ETH_Init 0 */

 static uint8_t MACAddr[6];

 /* USER CODE BEGIN ETH_Init 1 */

 /* USER CODE END ETH_Init 1 */
 heth.Instance = ETH;
 MACAddr[0] = 0x00;
 MACAddr[1] = 0x80;
 MACAddr[2] = 0xE1;
 MACAddr[3] = 0x00;
 MACAddr[4] = 0x00;
 MACAddr[5] = 0x00;
 heth.Init.MACAddr = &MACAddr[0];
 heth.Init.MediaInterface = HAL_ETH_RMII_MODE;
 heth.Init.TxDesc = DMATxDscrTab;
 heth.Init.RxDesc = DMARxDscrTab;
 heth.Init.RxBuffLen = 1524;

 /* USER CODE BEGIN MACADDRESS */

 /* USER CODE END MACADDRESS */

 if (HAL_ETH_Init(&heth) != HAL_OK)
 {
 Error_Handler();
 }

 memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
 TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
 TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
 TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
 /* USER CODE BEGIN ETH_Init 2 */

 /* USER CODE END ETH_Init 2 */

}

/**
 * @brief SPI1 Initialization Function
 * @PAram None
 * @retval None
 */
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_SLAVE;
 hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
 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.FirstBit = SPI_FIRSTBIT_MSB;
 hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
 hspi1.Init.CRCPolynomial = 10;
 if (HAL_SPI_Init(&hspi1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN SPI1_Init 2 */

 /* USER CODE END SPI1_Init 2 */

}

/**
 * @brief USART3 Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_USART3_UART_Init(void)
{

 /* USER CODE BEGIN USART3_Init 0 */

 /* USER CODE END USART3_Init 0 */

 /* USER CODE BEGIN USART3_Init 1 */

 /* USER CODE END USART3_Init 1 */
 huart3.Instance = USART3;
 huart3.Init.BaudRate = 115200;
 huart3.Init.WordLength = UART_WORDLENGTH_8B;
 huart3.Init.StopBits = UART_STOPBITS_1;
 huart3.Init.Parity = UART_PARITY_NONE;
 huart3.Init.Mode = UART_MODE_TX_RX;
 huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart3.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_UART_Init(&huart3) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART3_Init 2 */

 /* USER CODE END USART3_Init 2 */

}

/**
 * @brief USB_OTG_FS Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_USB_OTG_FS_PCD_Init(void)
{

 /* USER CODE BEGIN USB_OTG_FS_Init 0 */

 /* USER CODE END USB_OTG_FS_Init 0 */

 /* USER CODE BEGIN USB_OTG_FS_Init 1 */

 /* USER CODE END USB_OTG_FS_Init 1 */
 hpcd_USB_OTG_FS.Instance = USB_OTG_FS;
 hpcd_USB_OTG_FS.Init.dev_endpoints = 4;
 hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL;
 hpcd_USB_OTG_FS.Init.dma_enable = DISABLE;
 hpcd_USB_OTG_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
 hpcd_USB_OTG_FS.Init.Sof_enable = ENABLE;
 hpcd_USB_OTG_FS.Init.low_power_enable = DISABLE;
 hpcd_USB_OTG_FS.Init.lpm_enable = DISABLE;
 hpcd_USB_OTG_FS.Init.vbus_sensing_enable = ENABLE;
 hpcd_USB_OTG_FS.Init.use_dedicated_ep1 = DISABLE;
 if (HAL_PCD_Init(&hpcd_USB_OTG_FS) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USB_OTG_FS_Init 2 */

 /* USER CODE END USB_OTG_FS_Init 2 */

}

/**
 * Enable DMA controller clock
 */
static void MX_DMA_Init(void)
{

 /* DMA controller clock enable */
 __HAL_RCC_DMA2_CLK_ENABLE();

 /* DMA interrupt init */
 /* DMA2_Stream0_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

}

/**
 * @brief GPIO Initialization Function
 * @PAram None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOC_CLK_ENABLE();
 __HAL_RCC_GPIOH_CLK_ENABLE();
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOG_CLK_ENABLE();

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOB, LD1_Pin|LD3_Pin|LD2_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(USB_PowerSwitchOn_GPIO_Port, USB_PowerSwitchOn_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin : USER_Btn_Pin */
 GPIO_InitStruct.Pin = USER_Btn_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(USER_Btn_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pins : LD1_Pin LD3_Pin LD2_Pin */
 GPIO_InitStruct.Pin = LD1_Pin|LD3_Pin|LD2_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 /*Configure GPIO pin : USB_PowerSwitchOn_Pin */
 GPIO_InitStruct.Pin = USB_PowerSwitchOn_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(USB_PowerSwitchOn_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pin : USB_OverCurrent_Pin */
 GPIO_InitStruct.Pin = USB_OverCurrent_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(USB_OverCurrent_GPIO_Port, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {
	if(hspi->Instance == hspi1.Instance && -1 == msgFromSPI) {
		 msgFromSPI = 1;
	}
}
/* USER CODE END 4 */

/**
 * @brief This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
 }
 /* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
 * @brief Reports the name of the source file and the source line number
 * where the assert_param error has occurred.
 * @PAram file: pointer to the source file name
 * @PAram line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
 /* USER CODE BEGIN 6 */
 /* User can add his own implementation to report the file name and line number,
 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

 

 

 

Thank you for your help.

Andrew Neil
Super User
September 19, 2024

No need to start a separate thread,  just update the existing one - Merged into the original thread.

Early on, @BarryWhit said:

"These kinds of manual delays are often indicators of poor design"

Have you tried addressing that?

ie, put some proper synchronisation between your master & slave.

eg, use the NSS signal.

 

Have you used a logic analyser to see what's happening on the wires?

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Dreamer3DAuthor
Associate III
September 19, 2024

Thank you for responding to me,

I already address the issue with manual delays. I removed the manual delays.

I also an Hardware NSS Signal: Output Signal for the Master and Input Signal for the Slave. But this also did not resolve the problem.  

I use an oscilloscope to analyze the data = "ABC", it looks correct for me IMG_0469.jpg

Andrew Neil
Super User
September 19, 2024

Doesn't your scope have a proper facility to capture screen shots - thus avoiding that glare, etc?

 


@Dreamer3D wrote:

I also an Hardware NSS Signal: Output Signal for the Master and Input Signal for the Slave. But this also did not resolve the problem.  


That's not the right right way to use NSS:

 /* USER CODE BEGIN 3 */
	 HAL_SPI_Transmit(&hspi1, message_tx, 5, HAL_MAX_DELAY);
	 HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);

	 HAL_Delay(200);
 }
 /* USER CODE END 3 */

 

NSS should be high when inactive, then pull it low at the start of a transmission, then high again at the end:

AndrewNeil_0-1726746873910.png

https://vanhunteradams.com/Protocols/SPI/SPI.html#:~:text=to%20start%20the%20transaction%2C%20the%20chip%2Dselect%20line%20is%20pulled%20low%20by%20the%20main.%20When%20the%20secondary%20device%20sees%20this%20line%20go%20low%2C%20it%20knows%20to%20expect%20(in%20this%20case)%208%20clock%20pulses 

 

 /* USER CODE BEGIN 3 */
	 HAL_GPIO_WritePin( NSS_PORT, NSS_PIN, GPIO_PIN_RESET ); // Assert NSS
	 HAL_SPI_Transmit(&hspi1, message_tx, 5, HAL_MAX_DELAY); // Do the transfer
	 HAL_GPIO_WritePin( NSS_PORT, NSS_PIN, GPIO_PIN_SET ); // Release NSS

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Dreamer3DAuthor
Associate III
September 19, 2024

I added the code for configuring the NSS on the Master, and did not change anything on the Slave, but this still did not resolve the problem. 

I want to add some additional information: when I run the slave, I receive the correct data for the first iteration. And if I re-run the slave, without re-running the master, I still got the right data on the first iteration. Does that mean the problem is on the slave side? 

Andrew Neil
Super User
September 19, 2024

You really need to get a logic analyser on the wires to see what's actually being transferred

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Dreamer3DAuthorBest answer
Associate III
September 25, 2024

Hello, 

It's finnaly some experimental work and ChatGPT who resolve the problem

look bellow at this response that ChatGPT gave me.

Apparently, the circular mode is perfect for continous data transfer 

Screenshot_DMA_MODE_STM32.png