2025-12-10 9:52 AM - last edited on 2025-12-12 12:38 AM by Saket_Om
i'm trying to receive some data by uart and send by spi, both dma normal mode, i've done comunication separately but when i join them get stuck on spi busy, i tried a lot rtos(queues and semaphores), i changed almost all the code, but i just can't do this alone, i need some help. I am starting now at this level of embedding sistem and i'll be greatfull if anyone cold help me.
this is my code for:
RTOS:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : freertos.c
* Description : Code for freertos applications
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
#include "usart.h"
#include "spi.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
uint8_t packet_id_inv_cont_stop_tx[] = {
0xFF, 0x32, 0x00, 0x60, 0x08
};
#define FRAME_SIZE 64
extern uint8_t uart_frame_buf[FRAME_SIZE];
extern uint8_t spi_work_buf[FRAME_SIZE];
extern volatile uint8_t frame_ready;
extern volatile uint8_t spi_tx_done;
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
uint32_t osQueueMsg;
uint32_t ProducerValue = 0, ConsumerValue = 0;
__IO uint32_t ProducerErrors = 0, ConsumerErrors = 0;
/* USER CODE END Variables */
/* Definitions for send */
osThreadId_t sendHandle;
const osThreadAttr_t send_attributes = {
.name = "send",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for receive */
osThreadId_t receiveHandle;
const osThreadAttr_t receive_attributes = {
.name = "receive",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityLow,
};
/* Definitions for spiTxSem */
osSemaphoreId_t spiTxSemHandle;
const osSemaphoreAttr_t spiTxSem_attributes = {
.name = "spiTxSem"
};
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
extern void sendCommand(uint8_t *msg_transmited, uint16_t tx_size/*, uint8_t *msg_received, uint16_t rx_size*/);
extern void printBuffer(uint8_t *buffer, uint16_t bufferSize);
extern void spi_send(uint8_t *spibuffer);
/* USER CODE END FunctionPrototypes */
void sendingData(void *argument);
void receivingData(void *argument);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/**
* @brief FreeRTOS initialization
* @PAram None
* @retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* Create the semaphores(s) */
/* creation of spiTxSem */
spiTxSemHandle = osSemaphoreNew(1, 0, &spiTxSem_attributes);
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of send */
sendHandle = osThreadNew(sendingData, (void*) spiTxSemHandle, &send_attributes);
/* creation of receive */
receiveHandle = osThreadNew(receivingData, (void*) spiTxSemHandle, &receive_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
}
/* USER CODE BEGIN Header_sendingData */
/**
* @brief Function implementing the myTask02 thread.
* @PAram argument: Not used
* @retval None
*/
/* USER CODE END Header_sendingData */
void sendingData(void *argument)
{
/* USER CODE BEGIN sendingData */
//printf("trying transmit");
//HAL_SPI_Transmit(&hspi2, cycle_buff, sizeof(cycle_buff), HAL_MAX_DELAY);
for(;;)
{
osSemaphoreAcquire(spiTxSemHandle, osWaitForever);
printBuffer(spi_work_buf, FRAME_SIZE);
//printf("\nok\n");
spi_tx_done = 0;
HAL_StatusTypeDef spi_state = HAL_SPI_Transmit_DMA(&hspi2, spi_work_buf, FRAME_SIZE);
osDelay(100);
while(spi_state == HAL_BUSY)
{
printf("busy\n");
osDelay(1000);
}
printf("spi state: %d\n", spi_state);
uint32_t timeout = 1000;
while(!spi_tx_done && timeout--) osDelay(1);
if(!spi_tx_done){
//timeout
}
}
/* USER CODE END sendingData */
}
/* USER CODE BEGIN Header_receivingData */
/**
* @brief Function implementing the receive thread.
* @PAram argument: Not used
* @retval None
*/
/* USER CODE END Header_receivingData */
void receivingData(void *argument)
{
/* USER CODE BEGIN receivingData */
/* Infinite loop */
for(;;)
{
HAL_UART_Receive_DMA(&huart1, uart_frame_buf, FRAME_SIZE);
if(frame_ready)
{
frame_ready = 0;
memcpy(spi_work_buf, uart_frame_buf, FRAME_SIZE);
osSemaphoreRelease(spiTxSemHandle);
}
osDelay(100);
}
/* USER CODE END receivingData */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */
main code:
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_USART2_UART_Init();
MX_USART1_UART_Init();
MX_SPI2_Init();
/* USER CODE BEGIN 2 */
while(HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin))
{
HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
HAL_Delay(100);
};
HAL_Delay(1000);
/*start reading rfids*/
start_reading();
//HAL_UART_Receive_DMA(&huart1, uart_frame_buf, FRAME_SIZE);
/* USER CODE END 2 */
/* Init scheduler */
osKernelInitialize(); /* Call init function for freertos objects (in cmsis_os2.c) */
MX_FREERTOS_Init();
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
{
//printf("epc = 1\n");
if(huart == &huart1){
frame_ready = 1;
HAL_GPIO_WritePin(READY_GPIO_Port, READY_Pin, GPIO_PIN_SET);
}
}
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
//printf("SPI Callback\n");
if (hspi == &hspi2)
{
// transmission has been sent
spi_tx_done=1;
HAL_GPIO_WritePin(READY_GPIO_Port, READY_Pin, GPIO_PIN_RESET);
}
}
the configurations about baudrate, gpio pins, spi polarity and modes maybe ok cause
i tested before, my problem is with joining them. this is my first post here, i'll read
sugestions too for my next post.
Post edited by ST moderator to be inline with community rules for the code sharing. Please read this post: How to insert source code.
Solved! Go to Solution.
2025-12-12 12:53 AM
Hello @Etienne_Lima
You should investigate why it return HAL_BUSY and not HAL_OK.
2025-12-12 12:53 AM
Hello @Etienne_Lima
You should investigate why it return HAL_BUSY and not HAL_OK.