cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103C8T as SPI slave

DBern.7
Associate II

Hello,

I'm trying to set up SPI communication between an MCU as master and the STM32 as slave. Data reception in the STM32 works fine, but I'm not being able to transmit data to the MCU from the STM32. I'm using the interrupt callback to read and send the data as follows:

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef * hspi)

{

HAL_SPI_Receive_IT(&hspi1, rxbyte, 1);

HAL_SPI_Transmit_IT(&hspi1, txbyte, 1);

}

I expect that in the second transmission, my MCU will get the data stored in the txbyte.

But STM32 is not sending the data, on the other hand, if I place the transmit function in the while loop:

 /* Infinite loop */

 /* USER CODE BEGIN WHILE */

 while (1)

 {

  /* USER CODE END WHILE */

 HAL_SPI_Transmit_IT(&hspi1, txbyte, 1);

  /* USER CODE BEGIN 3 */

 }

The transmission occurs, but now the transmission buffer is filed with the data in txbyte.

Is there an explanation to this behavior? the SPI configuration is as follows:

0693W00000JP2YLQA1.png Thanks in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

> HAL_SPI_Receive_IT(&hspi1, rxbyte, 1);

> HAL_SPI_Transmit_IT(&hspi1, txbyte, 1);

SPI is not asynchronous TX/RX. Either you transmit, receive, or do both, but you can't have an RX transaction going and then try to start a TX one.

You may want HAL_SPI_TransmitReceive_IT.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

3 REPLIES 3
TDK
Guru

> HAL_SPI_Receive_IT(&hspi1, rxbyte, 1);

> HAL_SPI_Transmit_IT(&hspi1, txbyte, 1);

SPI is not asynchronous TX/RX. Either you transmit, receive, or do both, but you can't have an RX transaction going and then try to start a TX one.

You may want HAL_SPI_TransmitReceive_IT.

If you feel a post has answered your question, please click "Accept as Solution".
ssipa.1
Associate II

MASTER:

#include "main.h"

#include "stm32f1xx_hal.h"

/* USER CODE BEGIN Includes */

#include "stdio.h"

#include "string.h"

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/

SPI_HandleTypeDef hspi2;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_SPI2_Init(void);

static void MX_USART1_UART_Init(void);

/* USER CODE BEGIN PFP */

/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

void print(char * buffer)

{

HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);

}

/* USER CODE END 0 */

/**

* @brief The application entry point.

*

* @retval None

*/

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_SPI2_Init();

MX_USART1_UART_Init();

/* USER CODE BEGIN 2 */

/* USER CODE END 2 */

/* Infinite loop */

/* USER CODE BEGIN WHILE */

for(uint8_t i = 0; ;i++)

{

int result = 0;

GPIOB->BSRR = (1 << 12);

HAL_SPI_TransmitReceive(&hspi2, (uint8_t *)&i, (uint8_t*)&result, 2, HAL_MAX_DELAY);

GPIOB->BRR = (1 << 12);

if (result != (i - 1))

{

print("nop");

}

HAL_Delay(10);

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

/**

* @brief System Clock Configuration

* @retval None

*/

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

/**Initializes the CPU, AHB and APB busses clocks

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

/**Initializes the CPU, AHB and APB busses 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_DIV2;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

/**Configure the Systick interrupt time

*/

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

/**Configure the Systick

*/

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

/* SPI2 init function */

static void MX_SPI2_Init(void)

{

/* SPI2 parameter configuration*/

hspi2.Instance = SPI2;

hspi2.Init.Mode = SPI_MODE_MASTER;

hspi2.Init.Direction = SPI_DIRECTION_2LINES;

hspi2.Init.DataSize = SPI_DATASIZE_8BIT;

hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;

hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;

hspi2.Init.NSS = SPI_NSS_SOFT;

hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;

hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi2.Init.TIMode = SPI_TIMODE_DISABLE;

hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi2.Init.CRCPolynomial = 10;

if (HAL_SPI_Init(&hspi2) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

/* USART1 init function */

static void MX_USART1_UART_Init(void)

{

huart1.Instance = USART1;

huart1.Init.BaudRate = 115200;

huart1.Init.WordLength = UART_WORDLENGTH_8B;

huart1.Init.StopBits = UART_STOPBITS_1;

huart1.Init.Parity = UART_PARITY_NONE;

huart1.Init.Mode = UART_MODE_TX_RX;

huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;

huart1.Init.OverSampling = UART_OVERSAMPLING_16;

if (HAL_UART_Init(&huart1) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

/** Configure pins as

* Analog

* Input

* Output

* EVENT_OUT

* EXTI

*/

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOD_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);

/*Configure GPIO pin Output Level */

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_5, GPIO_PIN_SET);

/*Configure GPIO pin : PC13 */

GPIO_InitStruct.Pin = GPIO_PIN_13;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

/*Configure GPIO pin : PB10 */

GPIO_InitStruct.Pin = GPIO_PIN_10;

GPIO_InitStruct.Mode = GPIO_MODE_INPUT;

GPIO_InitStruct.Pull = GPIO_PULLDOWN;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/*Configure GPIO pins : PB12 PB5 */

GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_5;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

SLAVE:

#include "main.h"

#include "stm32f1xx_hal.h"

/* USER CODE BEGIN Includes */

#include "stdio.h"

#include "string.h"

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/

SPI_HandleTypeDef hspi2;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */

/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_SPI2_Init(void);

static void MX_USART1_UART_Init(void);

/* USER CODE BEGIN PFP */

/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

void print(char * buffer)

{

HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);

}

Thanks, now transmission works, but the function  HAL_SPI_TransmitReceive_IT is not triggering HAL_SPI_RxCpltCallback nor HAL_SPI_IRQHandler do you know how can I trigger an interrupt using HAL_SPI_TransmitReceive_IT?