2025-01-05 12:26 PM - edited 2025-01-05 12:48 PM
Hi everyone,
I am working with the STM32WLE and would like to use the internal SubGHz module directly without relying on any middleware, such as LoRaWAN. My goal is to control the SubGHz module in a simple way, similar to an external RF module like the SX1276 or RFM69.
Goals:
Questions:
What I’m Looking For: I want to operate the SubGHz module as if it were a standalone RF chip, like the SX126x or RFM69, with basic control over SPI or equivalent HAL/LL functions.
If anyone has experience with this or knows how to implement such functionality, I would appreciate your guidance.
Thanks in advance for your help! EDIT: I don’t care about the RF switches for now; I’ll handle them later once the basics are working. I’m using a custom board and want to avoid using the BSP. Ideally, I’d like everything in main.c with short, straightforward code, without unnecessary abstraction or additional layers—if that’s possible.
Best regards,
2025-01-06 05:30 AM
Hello @benultima and welcome to the ST Community.
For such an implementation, I suggest you refer to the chapter 4 of the RM0461 specially the paragraph 4.9. There is a full description for both transmission and reception of data throw the STM32WLE. You can also inspire from the SUBGHZ_Tx_Mode.
Best Regards.
STTwo-32
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-01-06 07:34 AM
Thank you for your reply, but I'm not able to get it to work. I'm trying the example, added all the necessary files from the Nucleo BSP library, and included some UART debug information. I can set it into standby mode, but I cannot manage to transmit using the example. I'm trying to program the LoRa-E5-HF module; maybe that's the problem, but I cannot identify the issue.
this is the debug output
=== Start Main ===
[Radio] Setting Sleep Mode.
[Radio] Setting Standby Mode.
[Radio] Retrieving Status.
[Radio] Radio is in Standby RC Mode.
[Radio] Setting TX Mode.
[Radio] Retrieving TX Status.
[Error] Radio is not in TX Mode.
#include "main.h"
#include <stdio.h>
#include <stdarg.h>
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
#define RADIO_MODE_STANDBY_RC 0x02
#define RADIO_MODE_TX 0x06
#define RADIO_COMMAND_TX_DONE 0x06
#define RADIO_MODE_BITFIELD 0x70
#define RADIO_STATUS_BITFIELD 0x0E
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
SUBGHZ_HandleTypeDef hsubghz;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
uint8_t RadioCmd[3] = {0x00, 0x00, 0x00};
uint8_t RadioResult = 0x00;
uint8_t RadioParam = 0x00;
uint8_t RadioMode = 0x00;
uint8_t RadioStatus = 0x00;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_SUBGHZ_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void Debug_Printf(const char *fmt, ...)
{
char buf[128];
va_list args;
va_start(args, fmt);
int len = vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
if (len > 0) {
HAL_UART_Transmit(&huart1, (uint8_t *)buf, len, HAL_MAX_DELAY);
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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 */
/* Configure LED2 & LED3 */
BSP_LED_Init(LED2);
BSP_LED_Init(LED3);
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_USART1_UART_Init();
MX_SUBGHZ_Init();
/* USER CODE BEGIN 2 */
/* USER CODE BEGIN 2 */
// Debug-Ausgabe
Debug_Printf("\r\n=== Start Main ===\r\n");
/*## 1 - Wakeup the SUBGHZ Radio ###########################################*/
/* Set Sleep Mode */
Debug_Printf("[Radio] Setting Sleep Mode.\r\n");
if (HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_SLEEP, &RadioParam, 1) != HAL_OK)
{
Error_Handler();
}
/* Set Standby Mode */
Debug_Printf("[Radio] Setting Standby Mode.\r\n");
if (HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_STANDBY, &RadioParam, 1) != HAL_OK)
{
Error_Handler();
}
/* Retrieve Status from SUBGHZ Radio */
Debug_Printf("[Radio] Retrieving Status.\r\n");
if (HAL_SUBGHZ_ExecGetCmd(&hsubghz, RADIO_GET_STATUS, &RadioResult, 1) != HAL_OK)
{
Error_Handler();
}
else
{
/* Format Mode and Status receive from SUBGHZ Radio */
RadioMode = ((RadioResult & RADIO_MODE_BITFIELD) >> 4);
/* Check if SUBGHZ Radio is in RADIO_MODE_STANDBY_RC mode */
if(RadioMode != RADIO_MODE_STANDBY_RC)
{
Error_Handler();
}
else
{
Debug_Printf("[Radio] Radio is in Standby RC Mode.\r\n");
}
}
/*## 2 - Set a TX on SUBGHZ Radio side #####################################*/
/* Set Tx Mode. RadioCmd = 0x00 Timeout deactivated */
Debug_Printf("[Radio] Setting TX Mode.\r\n");
if (HAL_SUBGHZ_ExecSetCmd(&hsubghz, RADIO_SET_TX, RadioCmd, 3) != HAL_OK)
{
Error_Handler();
}
/*## 3 - Get TX status from SUBGHZ Radio side ##############################*/
/* Check that TX is well ongoing (RADIO_MODE_TX), wait end of transfer */
/* Reset RadioResult */
RadioResult = 0x00;
/* Retrieve Status from SUBGHZ Radio */
Debug_Printf("[Radio] Retrieving TX Status.\r\n");
if (HAL_SUBGHZ_ExecGetCmd(&hsubghz, RADIO_GET_STATUS, &RadioResult, 1) != HAL_OK)
{
Error_Handler();
}
/* Format Mode and Status receive from SUBGHZ Radio */
RadioMode = ((RadioResult & RADIO_MODE_BITFIELD) >> 4);
RadioStatus = ((RadioResult & RADIO_STATUS_BITFIELD) >> 1);
if (RadioMode == RADIO_MODE_TX)
{
Debug_Printf("[Radio] TX Mode active. Waiting for transfer to complete.\r\n");
/* Wait end of transfer. SUBGHZ Radio go in Standby Mode */
do
{
/* Reset RadioResult */
RadioResult = 0x00;
/* Retrieve Status from SUBGHZ Radio */
if (HAL_SUBGHZ_ExecGetCmd(&hsubghz, RADIO_GET_STATUS, &RadioResult, 1) != HAL_OK)
{
Error_Handler();
}
/* Format Mode and Status receive from SUBGHZ Radio */
RadioMode = ((RadioResult & RADIO_MODE_BITFIELD) >> 4);
RadioStatus = ((RadioResult & RADIO_STATUS_BITFIELD) >> 1);
}
while (RadioMode != RADIO_MODE_STANDBY_RC);
}
else
{
/* Call Error Handler; LED1 blinking */
Debug_Printf("[Error] Radio is not in TX Mode.\r\n");
Error_Handler();
}
/* Check if TX is well done (SUBGHZ Radio already in Standby mode) */
if (RadioStatus == RADIO_COMMAND_TX_DONE)
{
/* Turn LED2 on */
Debug_Printf("[Radio] TX Done. Turning on LED2.\r\n");
BSP_LED_On(LED2);
}
else
{
/* Call Error Handler; LED1 blinking */
Debug_Printf("[Error] TX not completed successfully.\r\n");
Error_Handler();
}
/* USER CODE END 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* 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 = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK3|RCC_CLOCKTYPE_HCLK
|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.AHBCLK3Divider = RCC_SYSCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
2025-01-06 10:35 AM
This is not the original topic. This question is related to another behavior. So, please close this post as answered by selecting as Best answer the comment that answer your original question. After that, create a new post for this new problem to give it more visibility.
Best Regards.
STTwo-32
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.