log fix (added f_extend), other changes

This commit is contained in:
ggw
2026-05-24 09:37:56 -05:00
parent 19e646286f
commit 7d7297b12f
54 changed files with 294 additions and 7603 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ struct dbl_buff {
extern struct dbl_buff<1024, usb_send> usb_buff;
extern struct dbl_buff<1024, uart_send> ble_buff;
extern struct dbl_buff<1024, sd_send> sd_buff;
extern struct dbl_buff<4096, sd_send> sd_buff;
volatile extern bool send_imu_usb;
volatile extern bool send_imu_ble;
+2 -1
View File
@@ -31,7 +31,7 @@ void initialize_ads131(SPI_HandleTypeDef *hspi1) {
cmd[2] = 0x00;
cmd[3] = 0b00001111;
cmd[4] = 0b00011111;
cmd[4] = 0b00011011;
cmd[5] = 0x00;
HAL_GPIO_WritePin(GPIOA, ADC_CS_Pin, GPIO_PIN_RESET);
@@ -67,6 +67,7 @@ void initialize_ads131(SPI_HandleTypeDef *hspi1) {
struct packet_adc p_adc;
// With 5MHz SPI ~30uS for transfer
void read_ads131(SPI_HandleTypeDef *hspi1) {
if (HAL_GPIO_ReadPin(GPIOA, ADC_DRDY_Pin) != GPIO_PIN_RESET) {
+13 -4
View File
@@ -5,9 +5,16 @@ void sd_send(uint8_t data[], uint32_t len) {
extern bool sd_ready;
extern FIL file;
if (sd_ready) {
//char buff[80];
//CDC_Transmit_FS((uint8_t*)"W\n\r", 3);
UINT bytes_written;
FRESULT res = f_write(&file, data, len, &bytes_written);
//if (res != FR_OK || bytes_written != db_size)) {}
//f_sync(&file);
//int cx = snprintf(buff, 80, "%d %d %ld %ld\n\r", res, bytes_written, len, *((uint32_t*)data));
//CDC_Transmit_FS((uint8_t*)buff, cx);
if (res != FR_OK || bytes_written != len) {
}
}
}
@@ -22,11 +29,13 @@ void usb_send(uint8_t data[], uint32_t len) {
void uart_send(uint8_t data[], uint32_t len) {
extern bool wb1mmc_ready;
if (wb1mmc_ready) {
HAL_UART_Transmit_DMA(&huart1, data, len);
wb1mmc_ready = false;
if (huart1.gState == HAL_UART_STATE_READY) {
HAL_UART_Transmit_DMA(&huart1, data, len);
wb1mmc_ready = false;
}
}
}
struct dbl_buff<1024, usb_send> usb_buff;
struct dbl_buff<1024, uart_send> ble_buff;
struct dbl_buff<1024, sd_send> sd_buff;
struct dbl_buff<4096, sd_send> sd_buff;
+6 -5
View File
@@ -39,20 +39,20 @@ void initialize_lsm6dsv(SPI_HandleTypeDef *hspi1) {
tx_buff[1] = 0x01; // I2C and I3C disabled
send_receive_lsm6dsv(tx_buff, rx_buff, 2);
tx_buff[0] = 0x09; // Set 120Hz data rate for fifo
tx_buff[1] = 0b01100110;
tx_buff[0] = 0x09; // Set 240Hz data rate for fifo
tx_buff[1] = 0b01110111;
send_receive_lsm6dsv(tx_buff, rx_buff, 2);
tx_buff[0] = 0x0D; // Set drdy based on fifo
tx_buff[1] = 0b00111000;
send_receive_lsm6dsv(tx_buff, rx_buff, 2);
tx_buff[0] = 0x10; // Set 120Hz accelerometer high performance
tx_buff[0] = 0x10; // Set 240Hz accelerometer high performance
tx_buff[1] = 0b00000111;
send_receive_lsm6dsv(tx_buff, rx_buff, 2);
tx_buff[0] = 0x11; // Set 120Hz gyro high performance
tx_buff[1] = 0b00000110;
tx_buff[0] = 0x11; // Set 240Hz gyro high performance
tx_buff[1] = 0b00000111;
send_receive_lsm6dsv(tx_buff, rx_buff, 2);
tx_buff[0] = 0x07;
@@ -66,6 +66,7 @@ void initialize_lsm6dsv(SPI_HandleTypeDef *hspi1) {
struct packet_imu p_imu;
// With 5MHz SPI, the transfer should take 0.2mS
void read_lsm6dsv(SPI_HandleTypeDef *hspi1) {
if (HAL_GPIO_ReadPin(GPIOC, IMU_DRDY_Pin) == GPIO_PIN_RESET) {
+52 -11
View File
@@ -114,6 +114,7 @@ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
volatile bool to_open_sd = false;
volatile bool to_close_sd = false;
volatile bool to_print_dir = false;
void comm_handler(uint8_t ch) {
switch (ch) {
@@ -150,7 +151,10 @@ void comm_handler(uint8_t ch) {
break;
case '?':
print_desc = true;
break;
break;
case 'l':
to_print_dir = true;
break;
}
}
@@ -181,27 +185,54 @@ void open_sd(void) {
return;
}
alignas(32) char buffer1[32];
int cx = snprintf(buffer1, 32, "%08lu.log", ((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT % 99999999);
int cx = snprintf(buffer1, 32, "%08lu.log", (((uint32_t)tim6_reloads) * (htim6.Init.Period + 1) + TIM6->CNT) % 99999999);
res = f_open(&file, buffer1, FA_WRITE | FA_CREATE_ALWAYS);
if (res != FR_OK) {
res = f_mount(NULL, "", 1);
return;
}
f_expand(&file, 1024 * 1024 * 100, 1);
unsigned int bw;
data_description(false, true);
sd_ready = true;
}
}
void close_sd(void) {
sd_ready = false;
to_close_sd = false;
if (sd_ready) {
f_sync(&file);
f_close(&file);
res = f_mount(NULL, "", 1);
void print_dirs(void) {
char buff[80];
FRESULT fr;
DIR dir;
FILINFO fno;
res = f_mount(&fs, "", 1);
fr = f_opendir(&dir, "");
while (1)
{
fr = f_readdir(&dir, &fno);
if (fr != FR_OK || fno.fname[0] == 0)
break;
// Skip directories just in case
if (fno.fattrib & AM_DIR)
continue;
int cx = snprintf(buff, 80, "%s %10lu\n\r", fno.fname, (unsigned long)fno.fsize);
CDC_Transmit_FS((uint8_t*)buff, cx);
}
f_closedir(&dir);
f_mount(NULL, "", 1);
}
void close_sd(void) {
if (!sd_ready) {
return;
}
to_close_sd = false;
res = f_sync(&file);
res = f_close(&file);
res = f_mount(NULL, "", 1);
sd_ready = false;
}
/* USER CODE END 0 */
@@ -269,6 +300,11 @@ int main(void)
read_ads131(&hspi1);
read_max30101(&hi2c1);
if (to_print_dir) {
to_print_dir = false;
print_dirs();
}
if (to_open_sd) {
open_sd();
}
@@ -303,15 +339,20 @@ int main(void)
write(p_vbatt);
}
if (usb_ready and total_tim6() - usb_buff.last_write > 4000) {
if (usb_ready and total_tim6() - usb_buff.last_write > 8000) {
extern dbl_buff<1024, usb_send> usb_buff;
usb_buff.send();
}
if (wb1mmc_ready and total_tim6() - ble_buff.last_write > 4000) {
if (wb1mmc_ready and total_tim6() - ble_buff.last_write > 8000) {
extern dbl_buff<1024, uart_send> ble_buff;
ble_buff.send();
}
if (sd_ready and total_tim6() - sd_buff.last_write > 8000) {
extern dbl_buff<4096, sd_send> sd_buff;
sd_buff.send();
}
}
/* USER CODE END 3 */
}
+1
View File
@@ -58,6 +58,7 @@ void initialize_max30101(I2C_HandleTypeDef *hi2c1) {
HAL_I2C_Mem_Read(hi2c1, 0xAE, 0x07, 1, p_spo2.bytes, 180, HAL_MAX_DELAY);
}
// 3mS transfer but shouldn't block...
void read_max30101(I2C_HandleTypeDef *hi2c1) {
if (print_ready) {
p_spo2.t = total_tim6();
+1 -1
View File
@@ -63,7 +63,7 @@
#define _USE_FASTSEEK 1
/* This option switches fast seek feature. (0:Disable or 1:Enable) */
#define _USE_EXPAND 0
#define _USE_EXPAND 1
/* This option switches f_expand function. (0:Disable or 1:Enable) */
#define _USE_CHMOD 0
+1 -1
View File
@@ -1,5 +1,5 @@
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [4.9.0-B19] date: [Fri May 08 12:05:31 CDT 2026]
# File automatically-generated by tool: [projectgenerator] version: [4.9.0-B19] date: [Sat May 23 22:49:48 CDT 2026]
##########################################################################################################################
# ------------------------------------------------
+2 -1
View File
@@ -62,10 +62,11 @@ Dma.USART1_TX.1.PeriphInc=DMA_PINC_DISABLE
Dma.USART1_TX.1.Priority=DMA_PRIORITY_LOW
Dma.USART1_TX.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
FATFS.BSP.number=1
FATFS.IPParameters=USE_DMA_CODE_SD,_USE_LFN,_MAX_SS,_FS_NORTC
FATFS.IPParameters=USE_DMA_CODE_SD,_USE_LFN,_MAX_SS,_FS_NORTC,_USE_EXPAND
FATFS.USE_DMA_CODE_SD=0
FATFS._FS_NORTC=1
FATFS._MAX_SS=512
FATFS._USE_EXPAND=1
FATFS._USE_LFN=0
FATFS0.BSP.STBoard=false
FATFS0.BSP.api=Unknown
+156 -72
View File
@@ -1,5 +1,6 @@
import numpy as np
import matplotlib.pyplot as plt
import scipy as sp
packet_definitions = b"""packet_rtc 1 28 uint32_t t 0 4 RTC_TimeTypeDef sTime 4 20 RTC_DateTypeDef sDate 24 4
packet_vbatt 2 8 uint32_t t 0 4 uint16_t vbatt_cnts 4 2
@@ -32,21 +33,10 @@ def get_type_list(lines):
i += 4
return types
def my_filter(arr):
inds = np.where(np.abs(np.diff(arr)) > 0.005)[0]
for ind in inds:
prev_ind = ind - 1
while prev_ind in inds:
prev_ind -= 1
next_ind = ind + 1
while next_ind in inds:
next_ind += 1
arr[ind] = 0.5 * arr[prev_ind] + 0.5 * arr[next_ind]
return arr
reds = []
irs = []
greens = []
ppg_freq_Hz = 50
def process_ppg(d, t):
global greens, reds, irs
for e in t['elements']:
@@ -56,19 +46,19 @@ def process_ppg(d, t):
reds += [int.from_bytes(block[3 * i : 3 * i + 3], byteorder = 'big') for i in range(0,60,3)]
irs += [int.from_bytes(block[3 * i : 3 * i + 3], byteorder = 'big') for i in range(1,60,3)]
greens += [int.from_bytes(block[3 * i : 3 * i + 3], byteorder = 'big') for i in range(2,60,3)]
if len(reds) > 400:
reds = reds[-400:]
irs = irs[-400:]
greens = greens[-400:]
fig, axs = plt.subplots(3)
axs[0].set_title('red')
axs[1].set_title('ir')
axs[2].set_title('green')
axs[0].plot(reds)
axs[1].plot(irs)
axs[2].plot(greens)
plt.savefig("ppg.png")
plt.close()
# if len(reds) > 400:
# reds = reds[-400:]
# irs = irs[-400:]
# greens = greens[-400:]
# fig, axs = plt.subplots(3)
# axs[0].set_title('red')
# axs[1].set_title('ir')
# axs[2].set_title('green')
# axs[0].plot(reds)
# axs[1].plot(irs)
# axs[2].plot(greens)
# plt.savefig("ppg.png")
# plt.close()
accs = []
gyros = []
@@ -93,66 +83,160 @@ def process_imu(d, t):
pass
#assert False
imu_sparse += 1
if imu_sparse % 5 == 4:
if len(gyros) > 1600:
gyros = gyros[-1600:]
accs = accs[-1600:]
fig, axs = plt.subplots(2)
g = np.array(gyros)
a = np.array(accs)
#np.save("gyros.npy", g)
#np.save("accs.npy", a)
a -= np.mean(a, axis = 0).reshape(1,3)
axs[0].set_ylabel("dps")
axs[0].plot(g[:,0])
axs[0].plot(g[:,1])
axs[0].plot(g[:,2])
axs[1].set_ylabel("g")
axs[1].plot(a[:,0])
axs[1].plot(a[:,1])
axs[1].plot(a[:,2])
plt.savefig("acc_gyro.png")
plt.close()
# imu_sparse += 1
# if imu_sparse % 5 == 4:
# if len(gyros) > 1600:
# gyros = gyros[-1600:]
# accs = accs[-1600:]
# fig, axs = plt.subplots(2)
# g = np.array(gyros)
# a = np.array(accs)
# #np.save("gyros.npy", g)
# #np.save("accs.npy", a)
# a -= np.mean(a, axis = 0).reshape(1,3)
# axs[0].set_ylabel("dps")
# axs[0].plot(g[:,0])
# axs[0].plot(g[:,1])
# axs[0].plot(g[:,2])
# axs[1].set_ylabel("g")
# axs[1].plot(a[:,0])
# axs[1].plot(a[:,1])
# axs[1].plot(a[:,2])
# plt.savefig("acc_gyro.png")
# plt.close()
ecgs = []
t1s = []
t2s = []
strains = []
ts = []
adc_sparse = 0
# Should be running at 488Hz
freq_Hz = 488.28125
max_hr_Hz = 240 / 60
def process_adc(d, t):
global ecgs, t1s, t2s, strains, adc_sparse
global ecgs, t1s, t2s, strains, adc_sparse, ts
for e in t['elements']:
block = d[e['offset']:e['offset'] + e['size']]
element_size = int(len(block) / e['n_elements'])
if e['name'] == b't':
ts.append((1 / 2000) * int.from_bytes(block[:4], byteorder = 'little', signed = True))
if e['name'] == b'ekg_readings_cnts[50]':
ecgs = ecgs + [(2.4 / (1<<24)) * int.from_bytes(block[4 * i : 4 * i + 4], byteorder = 'little', signed = True) for i in range(50)]
adc_sparse += 1
if adc_sparse % 10 == 9:
if len(ecgs) > 200:
ecgs = ecgs[-2048:]
t1s = t1s[-205:]
t2s = t2s[-205:]
strains = strains[-205:]
fig, axs = plt.subplots(1)
axs.set_title("ECG")
#axs[1].set_title("Strain")
#axs[2].set_title("oT")
#axs[3].set_title("iT")
axs.plot(ecgs)
#axs[1].plot(strains)
#axs[2].plot(t1s)
#axs[3].plot(t2s)
fig.tight_layout()
plt.savefig("adcs.png")
plt.close()
if e['name'] == b'str_readings_cnts[5]':
strains = strains + [int.from_bytes(block[4 * i : 4 * i + 4], byteorder = 'little', signed = True) for i in range(5)]
if e['name'] == b'oT_readings_cnts[5]':
t1s = t1s + [int.from_bytes(block[4 * i : 4 * i + 4], byteorder = 'little', signed = True) for i in range(5)]
if e['name'] == b'iT_readings_cnts[5]':
t2s = t2s + [int.from_bytes(block[4 * i : 4 * i + 4], byteorder = 'little', signed = True) for i in range(5)]
# adc_sparse += 1
# if adc_sparse % 10 == 9:
# if len(ecgs) > 200:
# ecgs = ecgs[-4 * 4096:]
# t1s = t1s[-4096:]
# t2s = t2s[-4096:]
# strains = strains[-4096:]
# fig, axs = plt.subplots(2)
# axs[0].set_title("ECG")
# #axs[2].plot(np.array(ts[-200:-1]), 1000 * np.diff(ts[-200:]),'k.',linestyle='--')
# #if len(ts) > 200:
# # axs[2].set_title(str((ts[-1] - ts[-200]) / 200))
# #axs[2].set_xlabel('S')
# #axs[2].set_ylabel('mS')
# #axs[1].set_title("Strain")
# #axs[2].set_title("oT")
# #axs[3].set_title("iT")
# # 0.25 * 244 Hz
# #b, a = sp.signal.butter(2, [1 / (0.5 * freq_Hz), 120 / (0.5 * freq_Hz)], btype = 'bandpass')
# #ecgs_ = sp.signal.filtfilt(b, a, ecgs)
# #beats = np.where(np.diff(ecgs_) < -0.0003)[0]
# #last_beat = -1000000
# #beats_ = []
# #for beat in beats:
# # if (beat - last_beat) / 488 > 1 / (max_hr_Hz):
# # last_beat = beat
# # beats_.append(beat)
# axs[0].plot(ecgs, 'k')
# r_peaks = sp.signal.find_peaks(ecgs, height = None, threshold = None, distance = freq_Hz / max_hr_Hz, width = 5, prominence = 0.001)[0]
# all_peaks = sp.signal.find_peaks(ecgs, height = None, threshold = None, width = 10, prominence = 0.0001)[0]
# # for peak in all_peaks:
# # ls = [e for e in r_peaks if peak - e < 0 and peak - e > -0.2 * freq_Hz]
# # if len(ls) >= 1:
# # axs.plot(peak, ecgs[peak], 'bo') # P peaks
# # for peak in all_peaks:
# # ls = [e for e in r_peaks if peak - e > 0 and peak - e < 0.4 * freq_Hz]
# # if len(ls) >= 1:
# # axs.plot(peak, ecgs[peak], 'yo') # T peaks
# for peak in r_peaks:
# axs[0].plot(peak, ecgs[peak], 'ro')
# if len(r_peaks) > 5:
# hr_bpm = np.mean(60 * freq_Hz / np.diff(r_peaks))
# #hrv_ms = 1000 * np.std(np.diff(r_peaks)) / freq_Hz
# hrv_rmssd_ms = 1000. * np.power(np.mean(np.power(np.diff(np.diff(r_peaks / freq_Hz)), 2)), 0.5)
# axs[0].set_title(f"ECG HR:{np.round(hr_bpm)}BPM HRV (RMSSD):{np.round(hrv_rmssd_ms)}ms")
# hist = np.histogram(np.diff(r_peaks), bins = 8)
# axs[1].plot(0.5 * (hist[1][1:] + hist[1][:-1]), hist[0])
# #axs[1].plot(strains)
# #axs[2].plot(t1s)
# #axs[3].plot(t2s)
# fig.tight_layout()
# plt.savefig("adcs.png")
# plt.close()
# fig, axs = plt.subplots()
# axs.plot(ts[1:], np.diff(ts), 'k.')
# plt.savefig("adc_ts.png")
if e['name'] == b'str_readings_cnts[5]':
strains = strains + [(2.4 / (1<<24)) * int.from_bytes(block[4 * i : 4 * i + 4], byteorder = 'little', signed = True) for i in range(5)]
if e['name'] == b'oT_readings_cnts[5]':
t1s = t1s + [(2.4 / (1<<24)) * int.from_bytes(block[4 * i : 4 * i + 4], byteorder = 'little', signed = True) for i in range(5)]
if e['name'] == b'iT_readings_cnts[5]':
t2s = t2s + [(2.4 / (1<<24)) * int.from_bytes(block[4 * i : 4 * i + 4], byteorder = 'little', signed = True) for i in range(5)]
def make_graphs():
fig, axs = plt.subplots(2,2)
b, a = sp.signal.butter(2, [1 / (0.5 * freq_Hz), 120 / (0.5 * freq_Hz)], btype = 'bandpass')
ecgs_ = sp.signal.filtfilt(b, a, ecgs)
r_peaks = sp.signal.find_peaks(ecgs, height = None, threshold = None, distance = freq_Hz / max_hr_Hz, width = 5, prominence = 0.001)[0]
axs[0][0].plot(np.arange(len(ecgs)) / freq_Hz, ecgs_, 'k.', linestyle='--')
for peak in r_peaks:
axs[0][0].plot(peak / freq_Hz, ecgs_[peak], 'ro')
axs[1][0].plot(r_peaks[:-1] / freq_Hz, 1 / (np.diff(r_peaks) /freq_Hz), 'k.')
b, a = sp.signal.butter(2, [0.05 / (0.5 * ppg_freq_Hz), 4 / (0.5 * ppg_freq_Hz)], btype = 'bandpass')
reds_ = sp.signal.filtfilt(b, a, reds)
#irs_ = sp.signal.filtfilt(b, a, irs)
#greens_ = sp.signal.filtfilt(b, a, greens)
P_r = np.log(np.abs(np.fft.rfft(reds_)))
P_i = np.log(np.abs(np.fft.rfft(irs)))
P_g = np.log(np.abs(np.fft.rfft(greens)))
#axs[0][1].plot(np.arange(P_r.shape[0]) * 1 / 200, P_r)
#axs[0][1].plot(P_i)
#axs[0][1].plot(P_g)
axs[0][1].plot(np.arange(len(reds)) / 50, reds_, color = 'red')
#ax2 = axs[0][1].twinx()
#ax2.plot(np.arange(len(reds)) / 50, irs_, color = 'magenta')
#ax3 = ax2.twinx()
#ax3.plot(np.arange(len(reds)) / 50, greens_, color = 'green')
#axs[1][1].plot(np.array(gyros)[:,0])
#axs[1][1].plot(np.array(gyros)[:,1])
#axs[1][1].plot(np.array(gyros)[:,2])
gs = np.array(gyros)
acs = np.array(accs)
f_gs = np.log(np.abs(np.fft.rfft(acs, axis = 0)))
axs[1][1].plot(f_gs[:,0], alpha = 0.25)
axs[1][1].plot(f_gs[:,1], alpha = 0.25)
axs[1][1].plot(f_gs[:,2], alpha = 0.25)
#axs[1][1].plot(strains)
#axs[1][1].plot(t1s)
#axs[1][1].plot(t2s)
plt.show()
def read_and_process(types, cons, size):
index = 0
+13 -6
View File
@@ -1,16 +1,23 @@
from packet_parser_helpers import *
import packet_parser_helpers
import time
log = open('first_real.LOG','rb').read()
import matplotlib.pyplot as plt
types = get_type_list(packet_definitions)
log = open('5-23-2026-first-10-min.LOG','rb').read()
types = packet_parser_helpers.get_type_list(packet_parser_helpers.packet_definitions)
index = 493
while index < len(log):
size = int.from_bytes(log[index:index + 4], byteorder = 'little', signed = False)
print("INDEX: " + str(index) + " SIZE: " + str(size) + " FILESIZE: " + str(len(log)))
cons = log[index + 4 : index + 4 + size]
read_and_process(types, cons, size)
#time.sleep(0.1)
try:
packet_parser_helpers.read_and_process(types, cons, size)
#time.sleep(0.1)
except IndexError:
break
index += 4 + size
packet_parser_helpers.make_graphs()
@@ -1,113 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file app_common.h
* @author MCD Application Team
* @brief App Common application configuration file for STM32WPAN Middleware.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef APP_COMMON_H
#define APP_COMMON_H
#ifdef __cplusplus
extern "C"{
#endif
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "app_conf.h"
/* -------------------------------- *
* Basic definitions *
* -------------------------------- */
#undef NULL
#define NULL 0
#undef FALSE
#define FALSE 0
#undef TRUE
#define TRUE (!0)
/* -------------------------------- *
* Critical Section definition *
* -------------------------------- */
#define BACKUP_PRIMASK() uint32_t primask_bit= __get_PRIMASK()
#define DISABLE_IRQ() __disable_irq()
#define RESTORE_PRIMASK() __set_PRIMASK(primask_bit)
/* -------------------------------- *
* Macro delimiters *
* -------------------------------- */
#define M_BEGIN do {
#define M_END } while(0)
/* -------------------------------- *
* Some useful macro definitions *
* -------------------------------- */
#ifndef MAX
#define MAX( x, y ) (((x)>(y))?(x):(y))
#endif
#ifndef MIN
#define MIN( x, y ) (((x)<(y))?(x):(y))
#endif
#define MODINC( a, m ) M_BEGIN (a)++; if ((a)>=(m)) (a)=0; M_END
#define MODDEC( a, m ) M_BEGIN if ((a)==0) (a)=(m); (a)--; M_END
#define MODADD( a, b, m ) M_BEGIN (a)+=(b); if ((a)>=(m)) (a)-=(m); M_END
#define MODSUB( a, b, m ) MODADD( a, (m)-(b), m )
#define PAUSE( t ) M_BEGIN \
__IO int _i; \
for ( _i = t; _i > 0; _i -- ); \
M_END
#define DIVF( x, y ) ((x)/(y))
#define DIVC( x, y ) (((x)+(y)-1)/(y))
#define DIVR( x, y ) (((x)+((y)/2))/(y))
#define SHRR( x, n ) ((((x)>>((n)-1))+1)>>1)
#define BITN( w, n ) (((w)[(n)/32] >> ((n)%32)) & 1)
#define BITNSET( w, n, b ) M_BEGIN (w)[(n)/32] |= ((U32)(b))<<((n)%32); M_END
/* -------------------------------- *
* Compiler *
* -------------------------------- */
#define PLACE_IN_SECTION( __x__ ) __attribute__((section (__x__)))
#ifdef WIN32
#define ALIGN(n)
#else
#define ALIGN(n) __attribute__((aligned(n)))
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*APP_COMMON_H */
@@ -1,709 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file app_conf.h
* @author MCD Application Team
* @brief Application configuration file for STM32WPAN Middleware.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef APP_CONF_H
#define APP_CONF_H
#include "hw.h"
#include "hw_conf.h"
#include "hw_if.h"
#include "ble_bufsize.h"
/******************************************************************************
* Application Config
******************************************************************************/
/**< generic parameters ******************************************************/
/**
* Define Tx Power
*/
#define CFG_TX_POWER (0x19) /* 0dBm */
/**
* Define Advertising parameters
*/
#define CFG_ADV_BD_ADDRESS (0x11aabbccddee)
#define CFG_FAST_CONN_ADV_INTERVAL_MIN (0x40) /**< 80ms */
#define CFG_FAST_CONN_ADV_INTERVAL_MAX (0x60) /**< 100ms */
#define CFG_LP_CONN_ADV_INTERVAL_MIN (0xA0) /**< 1s */
#define CFG_LP_CONN_ADV_INTERVAL_MAX (0x140) /**< 2.5s */
/**
* Define IO Authentication
*/
#define CFG_BONDING_MODE (0)
#define CFG_ENCRYPTION_KEY_SIZE_MAX (16)
#define CFG_ENCRYPTION_KEY_SIZE_MIN (8)
/**
* Define IO capabilities
*/
#define CFG_IO_CAPABILITY_DISPLAY_ONLY (0x00)
#define CFG_IO_CAPABILITY_DISPLAY_YES_NO (0x01)
#define CFG_IO_CAPABILITY_KEYBOARD_ONLY (0x02)
#define CFG_IO_CAPABILITY_NO_INPUT_NO_OUTPUT (0x03)
#define CFG_IO_CAPABILITY_KEYBOARD_DISPLAY (0x04)
#define CFG_IO_CAPABILITY CFG_IO_CAPABILITY_DISPLAY_YES_NO
/**
* Define MITM modes
*/
#define CFG_MITM_PROTECTION_NOT_REQUIRED (0x00)
#define CFG_MITM_PROTECTION_REQUIRED (0x01)
#define CFG_MITM_PROTECTION CFG_MITM_PROTECTION_NOT_REQUIRED
/**
* Define Secure Connections Support
*/
#define CFG_SECURE_NOT_SUPPORTED (0x00)
#define CFG_SECURE_OPTIONAL (0x01)
#define CFG_SECURE_MANDATORY (0x02)
#define CFG_SC_SUPPORT CFG_SECURE_OPTIONAL
/**
* Define Keypress Notification Support
*/
#define CFG_KEYPRESS_NOT_SUPPORTED (0x00)
#define CFG_KEYPRESS_SUPPORTED (0x01)
#define CFG_KEYPRESS_NOTIFICATION_SUPPORT CFG_KEYPRESS_NOT_SUPPORTED
/**
* Numeric Comparison Answers
*/
#define YES (0x01)
#define NO (0x00)
/**
* Device name configuration for Generic Access Service
*/
#define CFG_GAP_DEVICE_NAME "TEMPLATE"
#define CFG_GAP_DEVICE_NAME_LENGTH (8)
/**
* Identity root key used to derive IRK and DHK(Legacy)
*/
#define CFG_BLE_IR {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0}
/**
* Encryption root key used to derive LTK(Legacy) and CSRK
*/
#define CFG_BLE_ER {0xFE, 0xDC, 0xBA, 0x09, 0x87, 0x65, 0x43, 0x21, 0xFE, 0xDC, 0xBA, 0x09, 0x87, 0x65, 0x43, 0x21}
/**
* SMPS supply
* SMPS not used when Set to 0
* SMPS used when Set to 1
*/
#define CFG_USE_SMPS 0
/* USER CODE BEGIN Generic_Parameters */
/* USER CODE END Generic_Parameters */
/**< specific parameters */
/*****************************************************/
/**
* Beacon selection
* Beacons are all exclusive
*/
#define CFG_EDDYSTONE_UID_BEACON_TYPE (1<<0)
#define CFG_EDDYSTONE_URL_BEACON_TYPE (1<<1)
#define CFG_EDDYSTONE_TLM_BEACON_TYPE (1<<2)
#define CFG_IBEACON (1<<3)
#define CFG_BEACON_TYPE (CFG_EDDYSTONE_UID_BEACON_TYPE)
#define OTA_BEACON_DATA_ADDRESS FLASH_BASE + 0x6000
#define OFFSET_PAYLOAD_LENGTH 9
#define OFFSET_PAYLOAD_DATA 10
/* USER CODE BEGIN Specific_Parameters */
/* USER CODE END Specific_Parameters */
/******************************************************************************
* BLE Stack
******************************************************************************/
/**
* Maximum number of simultaneous connections that the device will support.
* Valid values are from 1 to 8
*/
#define CFG_BLE_NUM_LINK 2
/**
* Maximum number of Services that can be stored in the GATT database.
* Note that the GAP and GATT services are automatically added so this parameter should be 2 plus the number of user services
*/
#define CFG_BLE_NUM_GATT_SERVICES 4
/**
* Maximum number of Attributes
* (i.e. the number of characteristic + the number of characteristic values + the number of descriptors, excluding the services)
* that can be stored in the GATT database.
* Note that certain characteristics and relative descriptors are added automatically during device initialization
* so this parameters should be 9 plus the number of user Attributes
*/
#define CFG_BLE_NUM_GATT_ATTRIBUTES 30
/**
* Maximum supported ATT_MTU size
* This parameter is ignored by the CPU2 when CFG_BLE_OPTIONS has SHCI_C2_BLE_INIT_OPTIONS_LL_ONLY flag set
*/
#define CFG_BLE_MAX_ATT_MTU (156)
/**
* Size of the storage area for Attribute values
* This value depends on the number of attributes used by application. In particular the sum of the following quantities (in octets) should be made for each attribute:
* - attribute value length
* - 5, if UUID is 16 bit; 19, if UUID is 128 bit
* - 2, if server configuration descriptor is used
* - 2*DTM_NUM_LINK, if client configuration descriptor is used
* - 2, if extended properties is used
* The total amount of memory needed is the sum of the above quantities for each attribute.
* This parameter is ignored by the CPU2 when CFG_BLE_OPTIONS has SHCI_C2_BLE_INIT_OPTIONS_LL_ONLY flag set
*/
#define CFG_BLE_ATT_VALUE_ARRAY_SIZE (1290)
/**
* Prepare Write List size in terms of number of packet
* This parameter is ignored by the CPU2 when CFG_BLE_OPTIONS has SHCI_C2_BLE_INIT_OPTIONS_LL_ONLY flag set
*/
#define CFG_BLE_PREPARE_WRITE_LIST_SIZE BLE_PREP_WRITE_X_ATT(CFG_BLE_MAX_ATT_MTU)
/**
* Number of allocated memory blocks
* This parameter is overwritten by the CPU2 with an hardcoded optimal value when the parameter CFG_BLE_OPTIONS has SHCI_C2_BLE_INIT_OPTIONS_LL_ONLY flag set
*/
#define CFG_BLE_MBLOCK_COUNT (BLE_MBLOCKS_CALC(CFG_BLE_PREPARE_WRITE_LIST_SIZE, CFG_BLE_MAX_ATT_MTU, CFG_BLE_NUM_LINK))
/**
* Enable or disable the Extended Packet length feature. Valid values are 0 or 1.
*/
#define CFG_BLE_DATA_LENGTH_EXTENSION 1
/**
* Sleep clock accuracy in Peripheral mode (ppm value)
*/
#define CFG_BLE_PERIPHERAL_SCA 500
/**
* Sleep clock accuracy in Central mode
* 0 : 251 ppm to 500 ppm
* 1 : 151 ppm to 250 ppm
* 2 : 101 ppm to 150 ppm
* 3 : 76 ppm to 100 ppm
* 4 : 51 ppm to 75 ppm
* 5 : 31 ppm to 50 ppm
* 6 : 21 ppm to 30 ppm
* 7 : 0 ppm to 20 ppm
*/
#define CFG_BLE_CENTRAL_SCA 0
/**
* LsSource
* Some information for Low speed clock mapped in bits field
* - bit 0: 1: Calibration for the RF system wakeup clock source 0: No calibration for the RF system wakeup clock source
* - bit 1: 1: STM32WB5M Module device 0: Other devices as STM32WBxx SOC, STM32WB1M module
* - bit 2: 1: HSE/1024 Clock config 0: LSE Clock config
* Note: Enable Calibration when LSI selected as RF system wakeup clock and "bit 2" is meaningless with LSI
*/
#if defined(STM32WB5Mxx)
#define CFG_BLE_LS_SOURCE (SHCI_C2_BLE_INIT_CFG_BLE_LS_NOCALIB | SHCI_C2_BLE_INIT_CFG_BLE_LS_MOD5MM_DEV | SHCI_C2_BLE_INIT_CFG_BLE_LS_CLK_LSE)
#else
#define CFG_BLE_LS_SOURCE (SHCI_C2_BLE_INIT_CFG_BLE_LS_NOCALIB | SHCI_C2_BLE_INIT_CFG_BLE_LS_OTHER_DEV | SHCI_C2_BLE_INIT_CFG_BLE_LS_CLK_LSE)
#endif
/**
* Start up time of the high speed (16 or 32 MHz) crystal oscillator in units of 625/256 us (~2.44 us)
*/
#define CFG_BLE_HSE_STARTUP_TIME 0x148
/**
* Maximum duration of the connection event when the device is in Peripheral mode in units of 625/256 us (~2.44 us)
*/
#define CFG_BLE_MAX_CONN_EVENT_LENGTH (0xFFFFFFFF)
/**
* Viterbi Mode
* 1 : enabled
* 0 : disabled
*/
#define CFG_BLE_VITERBI_MODE 1
/**
* BLE stack Options flags to be configured with:
* - SHCI_C2_BLE_INIT_OPTIONS_LL_ONLY
* - SHCI_C2_BLE_INIT_OPTIONS_LL_HOST
* - SHCI_C2_BLE_INIT_OPTIONS_NO_SVC_CHANGE_DESC
* - SHCI_C2_BLE_INIT_OPTIONS_WITH_SVC_CHANGE_DESC
* - SHCI_C2_BLE_INIT_OPTIONS_DEVICE_NAME_RO
* - SHCI_C2_BLE_INIT_OPTIONS_DEVICE_NAME_RW
* - SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV
* - SHCI_C2_BLE_INIT_OPTIONS_NO_EXT_ADV
* - SHCI_C2_BLE_INIT_OPTIONS_CS_ALGO2
* - SHCI_C2_BLE_INIT_OPTIONS_NO_CS_ALGO2
* - SHCI_C2_BLE_INIT_OPTIONS_REDUC_GATTDB_NVM
* - SHCI_C2_BLE_INIT_OPTIONS_FULL_GATTDB_NVM
* - SHCI_C2_BLE_INIT_OPTIONS_GATT_CACHING_USED
* - SHCI_C2_BLE_INIT_OPTIONS_GATT_CACHING_NOTUSED
* - SHCI_C2_BLE_INIT_OPTIONS_POWER_CLASS_1
* - SHCI_C2_BLE_INIT_OPTIONS_POWER_CLASS_2_3
* which are used to set following configuration bits:
* (bit 0): 1: LL only
* 0: LL + host
* (bit 1): 1: no service change desc.
* 0: with service change desc.
* (bit 2): 1: device name Read-Only
* 0: device name R/W
* (bit 3): 1: extended advertizing supported
* 0: extended advertizing not supported
* (bit 4): 1: CS Algo #2 supported
* 0: CS Algo #2 not supported
* (bit 5): 1: Reduced GATT database in NVM
* 0: Full GATT database in NVM
* (bit 6): 1: GATT caching is used
* 0: GATT caching is not used
* (bit 7): 1: LE Power Class 1
* 0: LE Power Class 2-3
* other bits: complete with Options_extension flag
*/
#define CFG_BLE_OPTIONS (SHCI_C2_BLE_INIT_OPTIONS_LL_HOST | SHCI_C2_BLE_INIT_OPTIONS_WITH_SVC_CHANGE_DESC | SHCI_C2_BLE_INIT_OPTIONS_DEVICE_NAME_RW | SHCI_C2_BLE_INIT_OPTIONS_NO_EXT_ADV | SHCI_C2_BLE_INIT_OPTIONS_NO_CS_ALGO2 | SHCI_C2_BLE_INIT_OPTIONS_FULL_GATTDB_NVM | SHCI_C2_BLE_INIT_OPTIONS_GATT_CACHING_NOTUSED | SHCI_C2_BLE_INIT_OPTIONS_POWER_CLASS_2_3)
/**
* BLE stack Options_extension flags to be configured with:
* - SHCI_C2_BLE_INIT_OPTIONS_APPEARANCE_WRITABLE
* - SHCI_C2_BLE_INIT_OPTIONS_APPEARANCE_READONLY
* - SHCI_C2_BLE_INIT_OPTIONS_ENHANCED_ATT_SUPPORTED
* - SHCI_C2_BLE_INIT_OPTIONS_ENHANCED_ATT_NOTSUPPORTED
* which are used to set following configuration bits:
* (bit 0): 1: appearance Writable
* 0: appearance Read-Only
* (bit 1): 1: Enhanced ATT supported
* 0: Enhanced ATT not supported
* other bits: reserved (shall be set to 0)
*/
#define CFG_BLE_OPTIONS_EXT (SHCI_C2_BLE_INIT_OPTIONS_APPEARANCE_READONLY | SHCI_C2_BLE_INIT_OPTIONS_ENHANCED_ATT_NOTSUPPORTED)
#define CFG_BLE_MAX_COC_INITIATOR_NBR (32)
#define CFG_BLE_MIN_TX_POWER (0)
#define CFG_BLE_MAX_TX_POWER (0)
/**
* BLE stack Maximum number of created Enhanced ATT bearers to be configured
* in addition to the number of links
* - Range: 0 .. 4
*/
#define CFG_BLE_MAX_ADD_EATT_BEARERS (4)
/**
* BLE Rx model configuration flags to be configured with:
* - SHCI_C2_BLE_INIT_RX_MODEL_AGC_RSSI_LEGACY
* - SHCI_C2_BLE_INIT_RX_MODEL_AGC_RSSI_BLOCKER
* which are used to set following configuration bits:
* (bit 0): 1: agc_rssi model improved vs RF blockers
* 0: Legacy agc_rssi model
* other bits: reserved (shall be set to 0)
*/
#define CFG_BLE_RX_MODEL_CONFIG (SHCI_C2_BLE_INIT_RX_MODEL_AGC_RSSI_LEGACY)
/* Maximum number of advertising sets.
* Range: 1 .. 8 with limitation:
* This parameter is linked to CFG_BLE_MAX_ADV_DATA_LEN such as both compliant with allocated Total memory computed with BLE_EXT_ADV_BUFFER_SIZE based
* on Max Extended advertising configuration supported.
* This parameter is considered by the CPU2 when CFG_BLE_OPTIONS has SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV flag set
*/
#define CFG_BLE_MAX_ADV_SET_NBR (2)
/* Maximum advertising data length (in bytes)
* Range: 31 .. 1650 with limitation:
* This parameter is linked to CFG_BLE_MAX_ADV_SET_NBR such as both compliant with allocated Total memory computed with BLE_EXT_ADV_BUFFER_SIZE based
* on Max Extended advertising configuration supported.
* This parameter is considered by the CPU2 when CFG_BLE_OPTIONS has SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV flag set
*/
#define CFG_BLE_MAX_ADV_DATA_LEN (1650)
/* RF TX Path Compensation Value (16-bit signed integer). Units: 0.1 dB.
* Range: -1280 .. 1280
*/
#define CFG_BLE_TX_PATH_COMPENS (0)
/* RF RX Path Compensation Value (16-bit signed integer). Units: 0.1 dB.
* Range: -1280 .. 1280
*/
#define CFG_BLE_RX_PATH_COMPENS (0)
/* BLE core version (16-bit signed integer).
* - SHCI_C2_BLE_INIT_BLE_CORE_5_2
* - SHCI_C2_BLE_INIT_BLE_CORE_5_3
* - SHCI_C2_BLE_INIT_BLE_CORE_5_4
* which are used to set: 11(5.2), 12(5.3), 13(5.4).
*/
#define CFG_BLE_CORE_VERSION (SHCI_C2_BLE_INIT_BLE_CORE_5_4)
/******************************************************************************
* Transport Layer
******************************************************************************/
/**
* Queue length of BLE Event
* This parameter defines the number of asynchronous events that can be stored in the HCI layer before
* being reported to the application. When a command is sent to the BLE core coprocessor, the HCI layer
* is waiting for the event with the Num_HCI_Command_Packets set to 1. The receive queue shall be large
* enough to store all asynchronous events received in between.
* When CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE is set to 27, this allow to store three 255 bytes long asynchronous events
* between the HCI command and its event.
* This parameter depends on the value given to CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE. When the queue size is to small,
* the system may hang if the queue is full with asynchronous events and the HCI layer is still waiting
* for a CC/CS event, In that case, the notification TL_BLE_HCI_ToNot() is called to indicate
* to the application a HCI command did not receive its command event within 30s (Default HCI Timeout).
*/
#define CFG_TLBLE_EVT_QUEUE_LENGTH 5
/**
* This parameter should be set to fit most events received by the HCI layer. It defines the buffer size of each element
* allocated in the queue of received events and can be used to optimize the amount of RAM allocated by the Memory Manager.
* It should not exceed 255 which is the maximum HCI packet payload size (a greater value is a lost of memory as it will
* never be used)
* It shall be at least 4 to receive the command status event in one frame.
* The default value is set to 27 to allow receiving an event of MTU size in a single buffer. This value maybe reduced
* further depending on the application.
*/
#define CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE 255 /**< Set to 255 with the memory manager and the mailbox */
#define TL_BLE_EVENT_FRAME_SIZE ( TL_EVT_HDR_SIZE + CFG_TLBLE_MOST_EVENT_PAYLOAD_SIZE )
/******************************************************************************
* UART interfaces
******************************************************************************/
/**
* Select UART interfaces
*/
#define CFG_DEBUG_TRACE_UART 0
#define CFG_CONSOLE_MENU 0
/******************************************************************************
* USB interface
******************************************************************************/
/**
* Enable/Disable USB interface
*/
#define CFG_USB_INTERFACE_ENABLE 0
/******************************************************************************
* IPCC interface
******************************************************************************/
/**
* The IPCC is dedicated to the communication between the CPU2 and the CPU1
* and shall not be modified by the application
* The two following definitions shall not be modified
*/
#define HAL_IPCC_TX_IRQHandler(...) HW_IPCC_Tx_Handler( )
#define HAL_IPCC_RX_IRQHandler(...) HW_IPCC_Rx_Handler( )
/******************************************************************************
* Low Power
******************************************************************************/
/**
* When set to 1, the low power mode is enable
* When set to 0, the device stays in RUN mode
*/
#define CFG_LPM_SUPPORTED 0
/**
* This shall be set to 1 when standby is supported while the wireless stack on CPU2 is running
* (i.e the CPU2 is allowed to enter standby between RF activity)
* Otherwise, it should be set to 0 for marginal code and test execution saving
* In this case the lowest power mode available will be Stop 1
* Note that keeping that setting to 1 when standby is not supported does not hurt
*/
#define CFG_LPM_STANDBY_SUPPORTED 0
/******************************************************************************
* RTC interface
******************************************************************************/
#define HAL_RTCEx_WakeUpTimerIRQHandler(...) HW_TS_RTC_Wakeup_Handler( )
/******************************************************************************
* Timer Server
******************************************************************************/
/**
* CFG_RTC_WUCKSEL_DIVIDER: This sets the RTCCLK divider to the wakeup timer.
* The lower is the value, the better is the power consumption and the accuracy of the timerserver
* The higher is the value, the finest is the granularity
*
* CFG_RTC_ASYNCH_PRESCALER: This sets the asynchronous prescaler of the RTC. It should as high as possible ( to output
* clock as low as possible) but the output clock should be equal or higher frequency compare to the clock feeding
* the wakeup timer. A lower clock speed would impact the accuracy of the timer server.
*
* CFG_RTC_SYNCH_PRESCALER: This sets the synchronous prescaler of the RTC.
* When the 1Hz calendar clock is required, it shall be sets according to other settings
* When the 1Hz calendar clock is not needed, CFG_RTC_SYNCH_PRESCALER should be set to 0x7FFF (MAX VALUE)
*
* CFG_RTCCLK_DIVIDER_CONF:
* Shall be set to either 0,2,4,8,16
* When set to either 2,4,8,16, the 1Hhz calendar is supported
* When set to 0, the user sets its own configuration
*
* The following settings are computed with LSI as input to the RTC
*/
#define CFG_RTCCLK_DIVIDER_CONF 0
#if (CFG_RTCCLK_DIVIDER_CONF == 0)
/**
* Custom configuration
* It does not support 1Hz calendar
* It divides the RTC CLK by 16
*/
#define CFG_RTCCLK_DIV (16)
#define CFG_RTC_WUCKSEL_DIVIDER (0)
#define CFG_RTC_ASYNCH_PRESCALER (0x0F)
#define CFG_RTC_SYNCH_PRESCALER (0x7FFF)
#else
#if (CFG_RTCCLK_DIVIDER_CONF == 2)
/**
* It divides the RTC CLK by 2
*/
#define CFG_RTC_WUCKSEL_DIVIDER (3)
#endif
#if (CFG_RTCCLK_DIVIDER_CONF == 4)
/**
* It divides the RTC CLK by 4
*/
#define CFG_RTC_WUCKSEL_DIVIDER (2)
#endif
#if (CFG_RTCCLK_DIVIDER_CONF == 8)
/**
* It divides the RTC CLK by 8
*/
#define CFG_RTC_WUCKSEL_DIVIDER (1)
#endif
#if (CFG_RTCCLK_DIVIDER_CONF == 16)
/**
* It divides the RTC CLK by 16
*/
#define CFG_RTC_WUCKSEL_DIVIDER (0)
#endif
#define CFG_RTCCLK_DIV CFG_RTCCLK_DIVIDER_CONF
#define CFG_RTC_ASYNCH_PRESCALER (CFG_RTCCLK_DIV - 1)
#define CFG_RTC_SYNCH_PRESCALER (DIVR( LSE_VALUE, (CFG_RTC_ASYNCH_PRESCALER+1) ) - 1 )
#endif
/** tick timer values */
#define CFG_TS_TICK_VAL DIVR( (CFG_RTCCLK_DIV * 1000000), LSE_VALUE )
#define CFG_TS_TICK_VAL_PS DIVR( ((uint64_t)CFG_RTCCLK_DIV * 1e12), (uint64_t)LSE_VALUE )
typedef enum
{
CFG_TIM_PROC_ID_ISR,
/* USER CODE BEGIN CFG_TimProcID_t */
/* USER CODE END CFG_TimProcID_t */
} CFG_TimProcID_t;
/******************************************************************************
* Debug
******************************************************************************/
/**
* When set, this resets some hw resources to put the device in the same state as at power up.
* It resets only register that may prevent the FW to run properly.
*
* This shall be set to 0 in a final product
*
*/
#define CFG_HW_RESET_BY_FW 0
/**
* keep debugger enabled while in any low power mode when set to 1
* should be set to 0 in production
*/
#define CFG_DEBUGGER_SUPPORTED 0
/**
* When set to 1, the traces are enabled in the BLE services
*/
#define CFG_DEBUG_BLE_TRACE 0
/**
* Enable or Disable traces in application
*/
#define CFG_DEBUG_APP_TRACE 0
#if (CFG_DEBUG_APP_TRACE != 0)
#define APP_DBG_MSG PRINT_MESG_DBG
#else
#define APP_DBG_MSG PRINT_NO_MESG
#endif
#if ( (CFG_DEBUG_BLE_TRACE != 0) || (CFG_DEBUG_APP_TRACE != 0) )
#define CFG_DEBUG_TRACE 1
#endif
#if (CFG_DEBUG_TRACE != 0)
#undef CFG_LPM_SUPPORTED
#undef CFG_DEBUGGER_SUPPORTED
#define CFG_LPM_SUPPORTED 0
#define CFG_DEBUGGER_SUPPORTED 1
#endif
/**
* When CFG_DEBUG_TRACE_FULL is set to 1, the trace are output with the API name, the file name and the line number
* When CFG_DEBUG_TRACE_LIGHT is set to 1, only the debug message is output
*
* When both are set to 0, no trace are output
* When both are set to 1, CFG_DEBUG_TRACE_FULL is selected
*/
#define CFG_DEBUG_TRACE_LIGHT 0
#define CFG_DEBUG_TRACE_FULL 0
#if (( CFG_DEBUG_TRACE != 0 ) && ( CFG_DEBUG_TRACE_LIGHT == 0 ) && (CFG_DEBUG_TRACE_FULL == 0))
#undef CFG_DEBUG_TRACE_FULL
#undef CFG_DEBUG_TRACE_LIGHT
#define CFG_DEBUG_TRACE_FULL 0
#define CFG_DEBUG_TRACE_LIGHT 1
#endif
#if ( CFG_DEBUG_TRACE == 0 )
#undef CFG_DEBUG_TRACE_FULL
#undef CFG_DEBUG_TRACE_LIGHT
#define CFG_DEBUG_TRACE_FULL 0
#define CFG_DEBUG_TRACE_LIGHT 0
#endif
/**
* When not set, the traces is looping on sending the trace over UART
*/
#define DBG_TRACE_USE_CIRCULAR_QUEUE 1
/**
* max buffer Size to queue data traces and max data trace allowed.
* Only Used if DBG_TRACE_USE_CIRCULAR_QUEUE is defined
*/
#define DBG_TRACE_MSG_QUEUE_SIZE 4096
#define MAX_DBG_TRACE_MSG_SIZE 1024
/* USER CODE BEGIN Defines */
/* USER CODE END Defines */
/******************************************************************************
* Scheduler
******************************************************************************/
/**
* These are the lists of task id registered to the scheduler
* Each task id shall be in the range [0:31]
* This mechanism allows to implement a generic code in the API TL_BLE_HCI_StatusNot() to comply with
* the requirement that a HCI/ACI command shall never be sent if there is already one pending
*/
/**< Add in that list all tasks that may send a ACI/HCI command */
typedef enum
{
CFG_TASK_BEACON_UPDATE_REQ_ID,
CFG_TASK_HCI_ASYNCH_EVT_ID,
/* USER CODE BEGIN CFG_Task_Id_With_HCI_Cmd_t */
/* USER CODE END CFG_Task_Id_With_HCI_Cmd_t */
CFG_LAST_TASK_ID_WITH_HCICMD, /**< Shall be LAST in the list */
} CFG_Task_Id_With_HCI_Cmd_t;
/**< Add in that list all tasks that never send a ACI/HCI command */
typedef enum
{
CFG_FIRST_TASK_ID_WITH_NO_HCICMD = CFG_LAST_TASK_ID_WITH_HCICMD - 1, /**< Shall be FIRST in the list */
CFG_TASK_SYSTEM_HCI_ASYNCH_EVT_ID,
/* USER CODE BEGIN CFG_Task_Id_With_NO_HCI_Cmd_t */
/* USER CODE END CFG_Task_Id_With_NO_HCI_Cmd_t */
CFG_LAST_TASK_ID_WITH_NO_HCICMD /**< Shall be LAST in the list */
} CFG_Task_Id_With_NO_HCI_Cmd_t;
#define CFG_TASK_NBR CFG_LAST_TASK_ID_WITH_NO_HCICMD
/**
* This is the list of priority required by the application
* Each Id shall be in the range 0..31
*/
typedef enum
{
CFG_SCH_PRIO_0,
/* USER CODE BEGIN CFG_SCH_Prio_Id_t */
/* USER CODE END CFG_SCH_Prio_Id_t */
CFG_SCH_PRIO_NBR
} CFG_SCH_Prio_Id_t;
/**
* This is a bit mapping over 32bits listing all events id supported in the application
*/
typedef enum
{
CFG_IDLEEVT_HCI_CMD_EVT_RSP_ID,
CFG_IDLEEVT_SYSTEM_HCI_CMD_EVT_RSP_ID,
/* USER CODE BEGIN CFG_IdleEvt_Id_t */
/* USER CODE END CFG_IdleEvt_Id_t */
} CFG_IdleEvt_Id_t;
/******************************************************************************
* LOW POWER
******************************************************************************/
/**
* Supported requester to the MCU Low Power Manager - can be increased up to 32
* It list a bit mapping of all user of the Low Power Manager
*/
typedef enum
{
CFG_LPM_APP,
CFG_LPM_APP_BLE,
/* USER CODE BEGIN CFG_LPM_Id_t */
/* USER CODE END CFG_LPM_Id_t */
} CFG_LPM_Id_t;
/******************************************************************************
* OTP manager
******************************************************************************/
#define CFG_OTP_BASE_ADDRESS OTP_AREA_BASE
#define CFG_OTP_END_ADRESS OTP_AREA_END_ADDR
#endif /*APP_CONF_H */
@@ -1,67 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file app_debug.h
* @author MCD Application Team
* @brief Header for app_debug.c module
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef APP_DEBUG_H
#define APP_DEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/* Exported macros ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions ---------------------------------------------*/
void APPD_Init( void );
void APPD_EnableCPU2( void );
/* USER CODE BEGIN EF */
/* USER CODE END EF */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*APP_DEBUG_H */
@@ -1,71 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file app_entry.h
* @author MCD Application Team
* @brief Interface to the application
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef APP_ENTRY_H
#define APP_ENTRY_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/* Exported macros ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions ---------------------------------------------*/
void MX_APPE_Config(void);
void MX_APPE_Init(void);
void MX_APPE_Process(void);
void Init_Exti(void);
void Init_Smps(void);
/* USER CODE BEGIN EF */
/* USER CODE END EF */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*APP_ENTRY_H */
@@ -1,52 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.h
* @brief This file contains all the function prototypes for
* the dma.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DMA_H__
#define __DMA_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* DMA memory to memory transfer handles -------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_DMA_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __DMA_H__ */
@@ -1,49 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file gpio.h
* @brief This file contains all the function prototypes for
* the gpio.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __GPIO_H__
#define __GPIO_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_GPIO_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__ GPIO_H__ */
@@ -1,173 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file hw_conf.h
* @author MCD Application Team
* @brief Configuration of hardware interface
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef HW_CONF_H
#define HW_CONF_H
/******************************************************************************
* Semaphores
* THIS SHALL NO BE CHANGED AS THESE SEMAPHORES ARE USED AS WELL ON THE CM0+
*****************************************************************************/
/**
* Index of the semaphore used the prevent conflicts after standby sleep.
* Each CPUs takes this semaphore at standby wakeup until conclicting elements are restored.
*/
#define CFG_HW_PWR_STANDBY_SEMID 10
/**
* The CPU2 may be configured to store the Thread persistent data either in internal NVM storage on CPU2 or in
* SRAM2 buffer provided by the user application. This can be configured with the system command SHCI_C2_Config()
* When the CPU2 is requested to store persistent data in SRAM2, it can write data in this buffer at any time when needed.
* In order to read consistent data with the CPU1 from the SRAM2 buffer, the flow should be:
* + CPU1 takes CFG_HW_THREAD_NVM_SRAM_SEMID semaphore
* + CPU1 reads all persistent data from SRAM2 (most of the time, the goal is to write these data into an NVM managed by CPU1)
* + CPU1 releases CFG_HW_THREAD_NVM_SRAM_SEMID semaphore
* CFG_HW_THREAD_NVM_SRAM_SEMID semaphore makes sure CPU2 does not update the persistent data in SRAM2 at the same time CPU1 is reading them.
* There is no timing constraint on how long this semaphore can be kept.
*/
#define CFG_HW_THREAD_NVM_SRAM_SEMID 9
/**
* The CPU2 may be configured to store the BLE persistent data either in internal NVM storage on CPU2 or in
* SRAM2 buffer provided by the user application. This can be configured with the system command SHCI_C2_Config()
* When the CPU2 is requested to store persistent data in SRAM2, it can write data in this buffer at any time when needed.
* In order to read consistent data with the CPU1 from the SRAM2 buffer, the flow should be:
* + CPU1 takes CFG_HW_BLE_NVM_SRAM_SEMID semaphore
* + CPU1 reads all persistent data from SRAM2 (most of the time, the goal is to write these data into an NVM managed by CPU1)
* + CPU1 releases CFG_HW_BLE_NVM_SRAM_SEMID semaphore
* CFG_HW_BLE_NVM_SRAM_SEMID semaphore makes sure CPU2 does not update the persistent data in SRAM2 at the same time CPU1 is reading them.
* There is no timing constraint on how long this semaphore can be kept.
*/
#define CFG_HW_BLE_NVM_SRAM_SEMID 8
/**
* Index of the semaphore used by CPU2 to prevent the CPU1 to either write or erase data in flash
* The CPU1 shall not either write or erase in flash when this semaphore is taken by the CPU2
* When the CPU1 needs to either write or erase in flash, it shall first get the semaphore and release it just
* after writing a raw (64bits data) or erasing one sector.
* Once the Semaphore has been released, there shall be at least 1us before it can be taken again. This is required
* to give the opportunity to CPU2 to take it.
* On v1.4.0 and older CPU2 wireless firmware, this semaphore is unused and CPU2 is using PES bit.
* By default, CPU2 is using the PES bit to protect its timing. The CPU1 may request the CPU2 to use the semaphore
* instead of the PES bit by sending the system command SHCI_C2_SetFlashActivityControl()
*/
#define CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID 7
/**
* Index of the semaphore used by CPU1 to prevent the CPU2 to either write or erase data in flash
* In order to protect its timing, the CPU1 may get this semaphore to prevent the CPU2 to either
* write or erase in flash (as this will stall both CPUs)
* The PES bit shall not be used as this may stall the CPU2 in some cases.
*/
#define CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID 6
/**
* Index of the semaphore used to manage the CLK48 clock configuration
* When the USB is required, this semaphore shall be taken before configuring te CLK48 for USB
* and should be released after the application switch OFF the clock when the USB is not used anymore
* When using the RNG, it is good enough to use CFG_HW_RNG_SEMID to control CLK48.
* More details in AN5289
*/
#define CFG_HW_CLK48_CONFIG_SEMID 5
/* Index of the semaphore used to manage the entry Stop Mode procedure */
#define CFG_HW_ENTRY_STOP_MODE_SEMID 4
/* Index of the semaphore used to access the RCC */
#define CFG_HW_RCC_SEMID 3
/* Index of the semaphore used to access the FLASH */
#define CFG_HW_FLASH_SEMID 2
/* Index of the semaphore used to access the PKA */
#define CFG_HW_PKA_SEMID 1
/* Index of the semaphore used to access the RNG */
#define CFG_HW_RNG_SEMID 0
/******************************************************************************
* HW TIMER SERVER
*****************************************************************************/
/**
* The user may define the maximum number of virtual timers supported.
* It shall not exceed 255
*/
#define CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER 6
/**
* The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the
* wakeup timer.
* This setting is the preemptpriority part of the NVIC.
*/
#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO 3
/**
* The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the
* wakeup timer.
* This setting is the subpriority part of the NVIC. It does not exist on all processors. When it is not supported
* on the CPU, the setting is ignored
*/
#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO 0
/**
* Define a critical section in the Timer server
* The Timer server does not support the API to be nested
* The Application shall either:
* a) Ensure this will never happen
* b) Define the critical section
* The default implementations is masking all interrupts using the PRIMASK bit
* The TimerServer driver uses critical sections to avoid context corruption. This is achieved with the macro
* TIMER_ENTER_CRITICAL_SECTION and TIMER_EXIT_CRITICAL_SECTION. When CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION is set
* to 1, all STM32 interrupts are masked with the PRIMASK bit of the CortexM CPU. It is possible to use the BASEPRI
* register of the CortexM CPU to keep allowed some interrupts with high priority. In that case, the user shall
* re-implement TIMER_ENTER_CRITICAL_SECTION and TIMER_EXIT_CRITICAL_SECTION and shall make sure that no TimerServer
* API are called when the TIMER critical section is entered
*/
#define CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION 1
/**
* This value shall reflect the maximum delay there could be in the application between the time the RTC interrupt
* is generated by the Hardware and the time when the RTC interrupt handler is called. This time is measured in
* number of RTCCLK ticks.
* A relaxed timing would be 10ms
* When the value is too short, the timerserver will not be able to count properly and all timeout may be random.
* When the value is too long, the device may wake up more often than the most optimal configuration. However, the
* impact on power consumption would be marginal (unless the value selected is extremely too long). It is strongly
* recommended to select a value large enough to make sure it is not too short to ensure reliability of the system
* as this will have marginal impact on low power mode
*/
#define CFG_HW_TS_RTC_HANDLER_MAX_DELAY ( 10 * (LSI_VALUE/1000) )
/**
* Interrupt ID in the NVIC of the RTC Wakeup interrupt handler
* It shall be type of IRQn_Type
*/
#define CFG_HW_TS_RTC_WAKEUP_HANDLER_ID RTC_WKUP_IRQn
/******************************************************************************
* HW UART
*****************************************************************************/
#define CFG_HW_LPUART1_ENABLED 0
#define CFG_HW_LPUART1_DMA_TX_SUPPORTED 0
#define CFG_HW_USART1_ENABLED 0
#define CFG_HW_USART1_DMA_TX_SUPPORTED 0
#endif /*HW_CONF_H */
@@ -1,247 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file hw_if.h
* @author MCD Application Team
* @brief Hardware Interface
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef HW_IF_H
#define HW_IF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx.h"
#include "stm32wbxx_ll_exti.h"
#include "stm32wbxx_ll_system.h"
#include "stm32wbxx_ll_rcc.h"
#include "stm32wbxx_ll_ipcc.h"
#include "stm32wbxx_ll_bus.h"
#include "stm32wbxx_ll_pwr.h"
#include "stm32wbxx_ll_cortex.h"
#include "stm32wbxx_ll_utils.h"
#include "stm32wbxx_ll_hsem.h"
#include "stm32wbxx_ll_gpio.h"
#include "stm32wbxx_ll_rtc.h"
#ifdef USE_STM32WBXX_USB_DONGLE
#include "stm32wbxx_usb_dongle.h"
#endif
#ifdef USE_STM32WBXX_NUCLEO
#include "nucleo_wb15cc.h"
#endif
#ifdef USE_X_NUCLEO_EPD
#include "x_nucleo_epd.h"
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/******************************************************************************
* HW UART
******************************************************************************/
typedef enum
{
hw_uart1,
hw_uart2,
hw_lpuart1,
} hw_uart_id_t;
typedef enum
{
hw_uart_ok,
hw_uart_error,
hw_uart_busy,
hw_uart_to,
} hw_status_t;
void HW_UART_Init(hw_uart_id_t hw_uart_id);
void HW_UART_Receive_IT(hw_uart_id_t hw_uart_id, uint8_t *pData, uint16_t Size, void (*Callback)(void));
void HW_UART_Transmit_IT(hw_uart_id_t hw_uart_id, uint8_t *pData, uint16_t Size, void (*Callback)(void));
hw_status_t HW_UART_Transmit(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, uint32_t timeout);
hw_status_t HW_UART_Transmit_DMA(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*Callback)(void));
void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id);
void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id);
/******************************************************************************
* HW TimerServer
******************************************************************************/
/* Exported types ------------------------------------------------------------*/
/**
* This setting is used when standby mode is supported.
* hw_ts_InitMode_Limited should be used when the device restarts from Standby Mode. In that case, the Timer Server does
* not re-initialized its context. Only the Hardware register which content has been lost is reconfigured
* Otherwise, hw_ts_InitMode_Full should be requested (Start from Power ON) and everything is re-initialized.
*/
typedef enum
{
hw_ts_InitMode_Full,
hw_ts_InitMode_Limited,
} HW_TS_InitMode_t;
/**
* When a Timer is created as a SingleShot timer, it is not automatically restarted when the timeout occurs. However,
* the timer is kept reserved in the list and could be restarted at anytime with HW_TS_Start()
*
* When a Timer is created as a Repeated timer, it is automatically restarted when the timeout occurs.
*/
typedef enum
{
hw_ts_SingleShot,
hw_ts_Repeated
} HW_TS_Mode_t;
/**
* hw_ts_Successful is returned when a Timer has been successfully created with HW_TS_Create(). Otherwise, hw_ts_Failed
* is returned. When hw_ts_Failed is returned, that means there are not enough free slots in the list to create a
* Timer. In that case, CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER should be increased
*/
typedef enum
{
hw_ts_Successful,
hw_ts_Failed,
}HW_TS_ReturnStatus_t;
typedef void (*HW_TS_pTimerCb_t)(void);
/**
* @brief Initialize the timer server
* This API shall be called by the application before any timer is requested to the timer server. It
* configures the RTC module to be connected to the LSI input clock.
*
* @param TimerInitMode: When the device restarts from Standby, it should request hw_ts_InitMode_Limited so that the
* Timer context is not re-initialized. Otherwise, hw_ts_InitMode_Full should be requested
* @param hrtc: RTC Handle
* @retval None
*/
void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *hrtc);
/**
* @brief Interface to create a virtual timer
* The user shall call this API to create a timer. Once created, the timer is reserved to the module until it
* has been deleted. When creating a timer, the user shall specify the mode (single shot or repeated), the
* callback to be notified when the timer expires and a module ID to identify in the timer interrupt handler
* which module is concerned. In return, the user gets a timer ID to handle it.
*
* @param TimerProcessID: This is an identifier provided by the user and returned in the callback to allow
* identification of the requester
* @param pTimerId: Timer Id returned to the user to request operation (start, stop, delete)
* @param TimerMode: Mode of the virtual timer (Single shot or repeated)
* @param pTimerCallBack: Callback when the virtual timer expires
* @retval HW_TS_ReturnStatus_t: Return whether the creation is successful or not
*/
HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pTimerCallBack);
/**
* @brief Stop a virtual timer
* This API may be used to stop a running timer. A timer which is stopped is move to the pending state.
* A pending timer may be restarted at any time with a different timeout value but the mode cannot be changed.
* Nothing is done when it is called to stop a timer which has been already stopped
*
* @param TimerID: Id of the timer to stop
* @retval None
*/
void HW_TS_Stop(uint8_t TimerID);
/**
* @brief Start a virtual timer
* This API shall be used to start a timer. The timeout value is specified and may be different each time.
* When the timer is in the single shot mode, it will move to the pending state when it expires. The user may
* restart it at any time with a different timeout value. When the timer is in the repeated mode, it always
* stay in the running state. When the timer expires, it will be restarted with the same timeout value.
* This API shall not be called on a running timer.
*
* @param TimerID: The ID Id of the timer to start
* @param timeout_ticks: Number of ticks of the virtual timer (Maximum value is (0xFFFFFFFF-0xFFFF = 0xFFFF0000)
* @retval None
*/
void HW_TS_Start(uint8_t TimerID, uint32_t timeout_ticks);
/**
* @brief Delete a virtual timer from the list
* This API should be used when a timer is not needed anymore by the user. A deleted timer is removed from
* the timer list managed by the timer server. It cannot be restarted again. The user has to go with the
* creation of a new timer if required and may get a different timer id
*
* @param TimerID: The ID of the timer to remove from the list
* @retval None
*/
void HW_TS_Delete(uint8_t TimerID);
/**
* @brief Schedule the timer list on the timer interrupt handler
* This interrupt handler shall be called by the application in the RTC interrupt handler. This handler takes
* care of clearing all status flag required in the RTC and EXTI peripherals
*
* @param None
* @retval None
*/
void HW_TS_RTC_Wakeup_Handler(void);
/**
* @brief Return the number of ticks to count before the interrupt
* This API returns the number of ticks left to be counted before an interrupt is generated by the
* Timer Server. This API may be used by the application for power management optimization. When the system
* enters low power mode, the mode selection is a tradeoff between the wakeup time where the CPU is running
* and the time while the CPU will be kept in low power mode before next wakeup. The deeper is the
* low power mode used, the longer is the wakeup time. The low power mode management considering wakeup time
* versus time in low power mode is implementation specific
* When the timer is disabled (No timer in the list), it returns 0xFFFF
*
* @param None
* @retval The number of ticks left to count
*/
uint16_t HW_TS_RTC_ReadLeftTicksToCount(void);
/**
* @brief Notify the application that a registered timer has expired
* This API shall be implemented by the user application.
* This API notifies the application that a timer expires. This API is running in the RTC Wakeup interrupt
* context. The application may implement an Operating System to change the context priority where the timer
* callback may be handled. This API provides the module ID to identify which module is concerned and to allow
* sending the information to the correct task
*
* @param TimerProcessID: The TimerProcessId associated with the timer when it has been created
* @param TimerID: The TimerID of the expired timer
* @param pTimerCallBack: The Callback associated with the timer when it has been created
* @retval None
*/
void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack);
/**
* @brief Notify the application that the wakeupcounter has been updated
* This API should be implemented by the user application
* This API notifies the application that the counter has been updated. This is expected to be used along
* with the HW_TS_RTC_ReadLeftTicksToCount () API. It could be that the counter has been updated since the
* last call of HW_TS_RTC_ReadLeftTicksToCount () and before entering low power mode. This notification
* provides a way to the application to solve that race condition to reevaluate the counter value before
* entering low power mode
*
* @param None
* @retval None
*/
void HW_TS_RTC_CountUpdated_AppNot(void);
#ifdef __cplusplus
}
#endif
#endif /*HW_IF_H */
@@ -1,52 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file ipcc.h
* @brief This file contains all the function prototypes for
* the ipcc.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __IPCC_H__
#define __IPCC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern IPCC_HandleTypeDef hipcc;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_IPCC_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __IPCC_H__ */
@@ -1,73 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32wbxx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define LED4_Pin GPIO_PIN_9
#define LED4_GPIO_Port GPIOA
#define LED5_Pin GPIO_PIN_5
#define LED5_GPIO_Port GPIOA
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
-50
View File
@@ -1,50 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file rf.h
* @brief This file contains all the function prototypes for
* the rf.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __RF_H__
#define __RF_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_RF_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __RF_H__ */
@@ -1,52 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file rtc.h
* @brief This file contains all the function prototypes for
* the rtc.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __RTC_H__
#define __RTC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern RTC_HandleTypeDef hrtc;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_RTC_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __RTC_H__ */
@@ -1,106 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file standby.h
* @author MCD Application Team
* @brief Header for standby.c module (specific code for standby low power mode)
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STANDBY_H
#define STANDBY_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported variables --------------------------------------------------------*/
extern uint32_t STBY_BootStatus;
extern uint16_t STBY_DebugGpioaPinList;
extern uint16_t STBY_DebugGpiobPinList;
extern uint16_t STBY_DebugGpiocPinList;
extern uint16_t STBY_DtbGpioaPinList;
extern uint16_t STBY_DtbGpiobPinList;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/* Exported macros ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions ---------------------------------------------*/
/**
* @brief Save necessary system HW data before entering into standby mode.
* @param none
* @retval none
*/
void STBY_SysHwSave(void);
/**
* @brief Save application HW data before entering into standby mode.
* @param none
* @retval none
*/
void STBY_AppHwSave(void);
/**
* @brief Restore necessary system HW data when exiting standby mode.
* @param none
* @retval none
*/
void STBY_SysHwRestore(void);
/**
* @brief Restore application HW data when exiting standby mode.
* @param none
* @retval none
*/
void STBY_AppHwRestore(void);
/**
* @brief Return the standby boot to perform.
* @param None
* @retval 1 if system can be restored after standby, else 0.
*/
uint32_t STBY_BootManager(void);
/* USER CODE BEGIN EF */
/* USER CODE END EF */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*STANDBY_H */
@@ -1,80 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32_lpm_if.h
* @author MCD Application Team
* @brief Header for stm32_lpm_if.c module (device specific LP management)
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32_LPM_IF_H
#define STM32_LPM_IF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
/**
* @brief Enters Low Power Off Mode
* @param none
* @retval none
*/
void PWR_EnterOffMode( void );
/**
* @brief Exits Low Power Off Mode
* @param none
* @retval none
*/
void PWR_ExitOffMode( void );
/**
* @brief Enters Low Power Stop Mode
* @note ARM exists the function when waking up
* @param none
* @retval none
*/
void PWR_EnterStopMode( void );
/**
* @brief Exits Low Power Stop Mode
* @note Enable the pll at 32MHz
* @param none
* @retval none
*/
void PWR_ExitStopMode( void );
/**
* @brief Enters Low Power Sleep Mode
* @note ARM exits the function when waking up
* @param none
* @retval none
*/
void PWR_EnterSleepMode( void );
/**
* @brief Exits Low Power Sleep Mode
* @note ARM exits the function when waking up
* @param none
* @retval none
*/
void PWR_ExitSleepMode( void );
#ifdef __cplusplus
}
#endif
#endif /*STM32_LPM_IF_H */
@@ -1,352 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32wbxx_hal_conf.h
* @author MCD Application Team
* @brief HAL configuration file.
******************************************************************************
* @attention
*
* Copyright (c) 2019 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32WBxx_HAL_CONF_H
#define __STM32WBxx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
/*#define HAL_ADC_MODULE_ENABLED */
/*#define HAL_CRYP_MODULE_ENABLED */
/*#define HAL_COMP_MODULE_ENABLED */
/*#define HAL_CRC_MODULE_ENABLED */
#define HAL_HSEM_MODULE_ENABLED
/*#define HAL_I2C_MODULE_ENABLED */
#define HAL_IPCC_MODULE_ENABLED
/*#define HAL_IRDA_MODULE_ENABLED */
/*#define HAL_IWDG_MODULE_ENABLED */
/*#define HAL_LCD_MODULE_ENABLED */
/*#define HAL_LPTIM_MODULE_ENABLED */
/*#define HAL_PCD_MODULE_ENABLED */
/*#define HAL_PKA_MODULE_ENABLED */
/*#define HAL_QSPI_MODULE_ENABLED */
/*#define HAL_RNG_MODULE_ENABLED */
#define HAL_RTC_MODULE_ENABLED
/*#define HAL_SAI_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
/*#define HAL_SPI_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
/*#define HAL_TSC_MODULE_ENABLED */
#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */
#define HAL_EXTI_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_GPIO_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define USE_HAL_ADC_REGISTER_CALLBACKS 0u
#define USE_HAL_COMP_REGISTER_CALLBACKS 0u
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u
#define USE_HAL_I2C_REGISTER_CALLBACKS 0u
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u
#define USE_HAL_PCD_REGISTER_CALLBACKS 0u
#define USE_HAL_PKA_REGISTER_CALLBACKS 0u
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0u
#define USE_HAL_RNG_REGISTER_CALLBACKS 0u
#define USE_HAL_RTC_REGISTER_CALLBACKS 0u
#define USE_HAL_SAI_REGISTER_CALLBACKS 0u
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u
#define USE_HAL_SPI_REGISTER_CALLBACKS 0u
#define USE_HAL_TIM_REGISTER_CALLBACKS 0u
#define USE_HAL_TSC_REGISTER_CALLBACKS 0u
#define USE_HAL_UART_REGISTER_CALLBACKS 1u
#define USE_HAL_USART_REGISTER_CALLBACKS 0u
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u
/* ########################## Oscillator Values adaptation ####################*/
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE 32000000U /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal Multiple Speed oscillator (MSI) default value.
* This value is the default MSI range value after Reset.
*/
#if !defined (MSI_VALUE)
#define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI1) value.
*/
#if !defined (LSI1_VALUE)
#define LSI1_VALUE ((uint32_t)32000) /*!< LSI1 Typical Value in Hz*/
#endif /* LSI1_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief Internal Low Speed oscillator (LSI2) value.
*/
#if !defined (LSI2_VALUE)
#define LSI2_VALUE ((uint32_t)32000) /*!< LSI2 Typical Value in Hz*/
#endif /* LSI2_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
* This value is used by the UART, RTC HAL module to compute the system frequency
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
/**
* @brief Internal Multiple Speed oscillator (HSI48) default value.
* This value is the default HSI48 range value after Reset.
*/
#if !defined (HSI48_VALUE)
#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI48_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for SAI1 peripheral
* This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
* frequency.
*/
#if !defined (EXTERNAL_SAI1_CLOCK_VALUE)
#define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)48000) /*!< Value of the SAI1 External clock source in Hz*/
#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY 15U /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32wbxx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32wbxx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_COMP_MODULE_ENABLED
#include "stm32wbxx_hal_comp.h"
#endif /* HAL_COMP_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32wbxx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32wbxx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32wbxx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32wbxx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32wbxx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32wbxx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_HSEM_MODULE_ENABLED
#include "stm32wbxx_hal_hsem.h"
#endif /* HAL_HSEM_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32wbxx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_IPCC_MODULE_ENABLED
#include "stm32wbxx_hal_ipcc.h"
#endif /* HAL_IPCC_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32wbxx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32wbxx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LCD_MODULE_ENABLED
#include "stm32wbxx_hal_lcd.h"
#endif /* HAL_LCD_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32wbxx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32wbxx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_PKA_MODULE_ENABLED
#include "stm32wbxx_hal_pka.h"
#endif /* HAL_PKA_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32wbxx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
#include "stm32wbxx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32wbxx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32wbxx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32wbxx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32wbxx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32wbxx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32wbxx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32wbxx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32wbxx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_TSC_MODULE_ENABLED
#include "stm32wbxx_hal_tsc.h"
#endif /* HAL_TSC_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32wbxx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32wbxx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32wbxx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* __STM32WBxx_HAL_CONF_H */
@@ -1,75 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32wbxx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32WBxx_IT_H
#define __STM32WBxx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void RCC_IRQHandler(void);
void DMA1_Channel1_IRQHandler(void);
void DMA1_Channel2_IRQHandler(void);
void TIM2_IRQHandler(void);
void USART1_IRQHandler(void);
void PWR_SOTF_BLEACT_RFPHASE_IRQHandler(void);
void IPCC_C1_RX_IRQHandler(void);
void IPCC_C1_TX_IRQHandler(void);
void HSEM_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32WBxx_IT_H */
@@ -1,52 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file tim.h
* @brief This file contains all the function prototypes for
* the tim.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __TIM_H__
#define __TIM_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern TIM_HandleTypeDef htim2;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_TIM2_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __TIM_H__ */
@@ -1,52 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.h
* @brief This file contains all the function prototypes for
* the usart.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_USART1_UART_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __USART_H__ */
@@ -1,65 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file utilities_conf.h
* @author MCD Application Team
* @brief Configuration file for STM32 Utilities.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef UTILITIES_CONF_H
#define UTILITIES_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
#include "cmsis_compiler.h"
#include "string.h"
#include "app_conf.h"
/******************************************************************************
* common
******************************************************************************/
#define UTILS_ENTER_CRITICAL_SECTION( ) uint32_t primask_bit = __get_PRIMASK( );\
__disable_irq( )
#define UTILS_EXIT_CRITICAL_SECTION( ) __set_PRIMASK( primask_bit )
#define UTILS_MEMSET8( dest, value, size ) memset( dest, value, size);
/******************************************************************************
* tiny low power manager
* (any macro that does not need to be modified can be removed)
******************************************************************************/
#define UTIL_LPM_INIT_CRITICAL_SECTION( )
#define UTIL_LPM_ENTER_CRITICAL_SECTION( ) UTILS_ENTER_CRITICAL_SECTION( )
#define UTIL_LPM_EXIT_CRITICAL_SECTION( ) UTILS_EXIT_CRITICAL_SECTION( )
/******************************************************************************
* sequencer
* (any macro that does not need to be modified can be removed)
******************************************************************************/
#define UTIL_SEQ_INIT_CRITICAL_SECTION( )
#define UTIL_SEQ_ENTER_CRITICAL_SECTION( ) UTILS_ENTER_CRITICAL_SECTION( )
#define UTIL_SEQ_EXIT_CRITICAL_SECTION( ) UTILS_EXIT_CRITICAL_SECTION( )
#define UTIL_SEQ_CONF_TASK_NBR (32)
#define UTIL_SEQ_CONF_PRIO_NBR CFG_SCH_PRIO_NBR
#define UTIL_SEQ_MEMSET8( dest, value, size ) UTILS_MEMSET8( dest, value, size )
#ifdef __cplusplus
}
#endif
#endif /*UTILITIES_CONF_H */
+1 -1
View File
@@ -210,7 +210,7 @@
* Maximum supported ATT_MTU size
* This parameter is ignored by the CPU2 when CFG_BLE_OPTIONS has SHCI_C2_BLE_INIT_OPTIONS_LL_ONLY flag set
*/
#define CFG_BLE_MAX_ATT_MTU (156)
#define CFG_BLE_MAX_ATT_MTU (512)
/**
* Size of the storage area for Attribute values
@@ -1,440 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file app_debug.c
* @author MCD Application Team
* @brief Debug capabilities source file for STM32WPAN Middleware
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 ------------------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "app_common.h"
#include "app_debug.h"
#include "utilities_common.h"
#include "shci.h"
#include "tl.h"
#include "dbg_trace.h"
#include "standby.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
typedef PACKED_STRUCT
{
GPIO_TypeDef* port;
uint16_t pin;
uint8_t enable;
uint8_t reserved;
} APPD_GpioConfig_t;
/* USER CODE END PTD */
/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define GPIO_NBR_OF_RF_SIGNALS 9
#define GPIO_CFG_NBR_OF_FEATURES 38
#define NBR_OF_TRACES_CONFIG_PARAMETERS 4
#define NBR_OF_GENERAL_CONFIG_PARAMETERS 14
/**
* THIS SHALL BE SET TO A VALUE DIFFERENT FROM 0 ONLY ON REQUEST FROM ST SUPPORT
*/
#define BLE_DTB_CFG 0
/**
* System Debug Options flags to be configured with:
* - SHCI_C2_DEBUG_OPTIONS_IPCORE_LP
* - SHCI_C2_DEBUG_OPTIONS_IPCORE_NO_LP
* - SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_EN
* - SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_DIS
* which are used to set following configuration bits:
* - bit 0: 0: IP BLE core in LP mode 1: IP BLE core in run mode (no LP supported)
* - bit 1: 0: CPU2 STOP mode Enable 1: CPU2 STOP mode Disable
* - bit [2-7]: bits reserved ( shall be set to 0)
*/
#define SYS_DBG_CFG1 (SHCI_C2_DEBUG_OPTIONS_IPCORE_LP | SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_EN)
/* USER CODE END PD */
/* Private macros ------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static SHCI_C2_DEBUG_TracesConfig_t APPD_TracesConfig={0, 0, 0, 0};
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static SHCI_C2_DEBUG_GeneralConfig_t APPD_GeneralConfig={BLE_DTB_CFG, SYS_DBG_CFG1, {0, 0}, 0, 0, 0, 0, 0};
#ifdef CFG_DEBUG_TRACE_UART
#if(CFG_HW_LPUART1_ENABLED == 1)
extern void MX_LPUART1_UART_Init(void);
#endif
#if(CFG_HW_USART1_ENABLED == 1)
extern void MX_USART1_UART_Init(void);
#endif
#endif
/**
* THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT
* It provides timing information on the CPU2 activity.
* All configuration of (port, pin) is supported for each features and can be selected by the user
* depending on the availability
*/
static const APPD_GpioConfig_t aGpioConfigList[GPIO_CFG_NBR_OF_FEATURES] =
{
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_ISR - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_STACK_TICK - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_CMD_PROCESS - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_ACL_DATA_PROCESS - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* SYS_CMD_PROCESS - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* RNG_PROCESS - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVM_PROCESS - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_GENERAL - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_BLE_CMD_RX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_BLE_EVT_TX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_BLE_ACL_DATA_RX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_SYS_CMD_RX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_SYS_EVT_TX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_CLI_CMD_RX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_OT_CMD_RX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_OT_ACK_TX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_CLI_ACK_TX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_MEM_MANAGER_RX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_TRACES_TX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* HARD_FAULT - Set on Entry / Reset on Exit */
/* From v1.1.1 */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IP_CORE_LP_STATUS - Set on Entry / Reset on Exit */
/* From v1.2.0 */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* END_OF_CONNECTION_EVENT - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* TIMER_SERVER_CALLBACK - Toggle on Entry */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* PES_ACTIVITY - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* MB_BLE_SEND_EVT - Set on Entry / Reset on Exit */
/* From v1.3.0 */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_NO_DELAY - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_STACK_STORE_NVM_CB - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVMA_WRITE_ONGOING - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVMA_WRITE_COMPLETE - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVMA_CLEANUP - Set on Entry / Reset on Exit */
/* From v1.4.0 */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* NVMA_START - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* FLASH_EOP - Set on Entry / Reset on Exit */
/* From v1.5.0 */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* FLASH_WRITE - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* FLASH_ERASE - Set on Entry / Reset on Exit */
/* From v1.6.0 */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_RESCHEDULE_EVENT - Set on Entry / Reset on Exit */
/* From v1.8.0 */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_BLE_LLD_CMD_RX - Set on Entry / Reset on Exit */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_BLE_LLD_ACK_TX - Set on Entry / Reset on Exit */
/* From v1.9.0 */
{ GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_ASYNCH_EVENT_NACKED - Set on Entry / Reset on Exit */
};
/**
* THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT
* This table is relevant only for BLE
* It provides timing information on BLE RF activity.
* New signals may be allocated at any location when requested by ST
* The GPIO allocated to each signal depend on the BLE_DTB_CFG value and cannot be changed
*/
#if( BLE_DTB_CFG == 7)
static const APPD_GpioConfig_t aRfConfigList[GPIO_NBR_OF_RF_SIGNALS] =
{
{ GPIOB, LL_GPIO_PIN_2, 0, 0}, /* DTB10 - Tx/Rx SPI */
{ GPIOB, LL_GPIO_PIN_7, 0, 0}, /* DTB11 - Tx/Tx SPI Clk */
{ GPIOA, LL_GPIO_PIN_8, 0, 0}, /* DTB12 - Tx/Rx Ready & SPI Select */
{ GPIOA, LL_GPIO_PIN_9, 0, 0}, /* DTB13 - Tx/Rx Start */
{ GPIOA, LL_GPIO_PIN_10, 0, 0}, /* DTB14 - FSM0 */
{ GPIOA, LL_GPIO_PIN_11, 0, 0}, /* DTB15 - FSM1 */
{ GPIOB, LL_GPIO_PIN_8, 0, 0}, /* DTB16 - FSM2 */
{ GPIOA, LL_GPIO_PIN_13, 0, 0}, /* DTB17 - FSM3 */
{ GPIOA, LL_GPIO_PIN_14, 0, 0}, /* DTB18 - FSM4 */
};
#endif
/* USER CODE END PV */
/* Global variables ----------------------------------------------------------*/
/* USER CODE BEGIN GV */
/* USER CODE END GV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
static void APPD_SetCPU2GpioConfig( void );
static void APPD_BleDtbCfg( void );
/* USER CODE END PFP */
/* Functions Definition ------------------------------------------------------*/
void APPD_Init( void )
{
/* USER CODE BEGIN APPD_Init */
#if (CFG_DEBUGGER_SUPPORTED == 1)
/**
* Keep debugger enabled while in any low power mode
*/
HAL_DBGMCU_EnableDBGSleepMode();
HAL_DBGMCU_EnableDBGStopMode();
/***************** ENABLE DEBUGGER *************************************/
LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48);
#else
GPIO_InitTypeDef gpio_config = {0};
gpio_config.Pull = GPIO_NOPULL;
gpio_config.Mode = GPIO_MODE_ANALOG;
gpio_config.Pin = GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_13;
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA, &gpio_config);
__HAL_RCC_GPIOA_CLK_DISABLE();
gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_3;
__HAL_RCC_GPIOB_CLK_ENABLE();
HAL_GPIO_Init(GPIOB, &gpio_config);
__HAL_RCC_GPIOB_CLK_DISABLE();
HAL_DBGMCU_DisableDBGSleepMode();
HAL_DBGMCU_DisableDBGStopMode();
HAL_DBGMCU_DisableDBGStandbyMode();
#endif /* (CFG_DEBUGGER_SUPPORTED == 1) */
#if(CFG_DEBUG_TRACE != 0)
DbgTraceInit();
#endif
APPD_SetCPU2GpioConfig( );
APPD_BleDtbCfg( );
/* USER CODE END APPD_Init */
return;
}
void APPD_EnableCPU2( void )
{
/* USER CODE BEGIN APPD_EnableCPU2 */
APPD_GeneralConfig.STBY_DebugGpioaPinList = STBY_DebugGpioaPinList;
APPD_GeneralConfig.STBY_DebugGpiobPinList = STBY_DebugGpiobPinList;
APPD_GeneralConfig.STBY_DebugGpiocPinList = STBY_DebugGpiocPinList;
APPD_GeneralConfig.STBY_DtbGpioaPinList = STBY_DtbGpioaPinList;
APPD_GeneralConfig.STBY_DtbGpiobPinList = STBY_DtbGpiobPinList;
SHCI_C2_DEBUG_Init_Cmd_Packet_t DebugCmdPacket =
{
{{0,0,0}}, /**< Does not need to be initialized */
{(uint8_t *)aGpioConfigList,
(uint8_t *)&APPD_TracesConfig,
(uint8_t *)&APPD_GeneralConfig,
GPIO_CFG_NBR_OF_FEATURES,
NBR_OF_TRACES_CONFIG_PARAMETERS,
NBR_OF_GENERAL_CONFIG_PARAMETERS}
};
/**< Traces channel initialization */
TL_TRACES_Init( );
/** GPIO DEBUG Initialization */
SHCI_C2_DEBUG_Init( &DebugCmdPacket );
/* USER CODE END APPD_EnableCPU2 */
return;
}
/*************************************************************
*
* LOCAL FUNCTIONS
*
*************************************************************/
static void APPD_SetCPU2GpioConfig( void )
{
/* USER CODE BEGIN APPD_SetCPU2GpioConfig */
GPIO_InitTypeDef gpio_config = {0};
uint8_t local_loop;
uint16_t gpioa_pin_list;
uint16_t gpiob_pin_list;
uint16_t gpioc_pin_list;
gpioa_pin_list = STBY_DebugGpioaPinList;
gpiob_pin_list = STBY_DebugGpiobPinList;
gpioc_pin_list = STBY_DebugGpiocPinList;
if(gpioa_pin_list == UINT16_MAX)
{
gpioa_pin_list = 0;
gpiob_pin_list = 0;
gpioc_pin_list = 0;
for(local_loop = 0 ; local_loop < GPIO_CFG_NBR_OF_FEATURES; local_loop++)
{
if( aGpioConfigList[local_loop].enable != 0)
{
switch((uint32_t)aGpioConfigList[local_loop].port)
{
case (uint32_t)GPIOA:
gpioa_pin_list |= aGpioConfigList[local_loop].pin;
break;
case (uint32_t)GPIOB:
gpiob_pin_list |= aGpioConfigList[local_loop].pin;
break;
case (uint32_t)GPIOC:
gpioc_pin_list |= aGpioConfigList[local_loop].pin;
break;
default:
break;
}
}
}
STBY_DebugGpioaPinList = gpioa_pin_list;
STBY_DebugGpiobPinList = gpiob_pin_list;
STBY_DebugGpiocPinList = gpioc_pin_list;
}
gpio_config.Pull = GPIO_NOPULL;
gpio_config.Mode = GPIO_MODE_OUTPUT_PP;
gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
if(gpioa_pin_list != 0)
{
gpio_config.Pin = gpioa_pin_list;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_C2GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA, &gpio_config);
HAL_GPIO_WritePin(GPIOA, gpioa_pin_list, GPIO_PIN_RESET);
}
if(gpiob_pin_list != 0)
{
gpio_config.Pin = gpiob_pin_list;
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_C2GPIOB_CLK_ENABLE();
HAL_GPIO_Init(GPIOB, &gpio_config);
HAL_GPIO_WritePin(GPIOB, gpiob_pin_list, GPIO_PIN_RESET);
}
if(gpioc_pin_list != 0)
{
gpio_config.Pin = gpioc_pin_list;
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_C2GPIOC_CLK_ENABLE();
HAL_GPIO_Init(GPIOC, &gpio_config);
HAL_GPIO_WritePin(GPIOC, gpioc_pin_list, GPIO_PIN_RESET);
}
/* USER CODE END APPD_SetCPU2GpioConfig */
return;
}
static void APPD_BleDtbCfg( void )
{
/* USER CODE BEGIN APPD_BleDtbCfg */
#if (BLE_DTB_CFG != 0)
GPIO_InitTypeDef gpio_config = {0};
uint8_t local_loop;
uint16_t gpioa_pin_list;
uint16_t gpiob_pin_list;
gpioa_pin_list = STBY_DtbGpioaPinList;
gpiob_pin_list = STBY_DtbGpiobPinList;
if(gpioa_pin_list == UINT16_MAX)
{
gpioa_pin_list = 0;
gpiob_pin_list = 0;
for(local_loop = 0 ; local_loop < GPIO_NBR_OF_RF_SIGNALS; local_loop++)
{
if( aRfConfigList[local_loop].enable != 0)
{
switch((uint32_t)aRfConfigList[local_loop].port)
{
case (uint32_t)GPIOA:
gpioa_pin_list |= aRfConfigList[local_loop].pin;
break;
case (uint32_t)GPIOB:
gpiob_pin_list |= aRfConfigList[local_loop].pin;
break;
default:
break;
}
}
}
STBY_DtbGpioaPinList = gpioa_pin_list;
STBY_DtbGpiobPinList = gpiob_pin_list;
}
gpio_config.Pull = GPIO_NOPULL;
gpio_config.Mode = GPIO_MODE_AF_PP;
gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio_config.Alternate = GPIO_AF6_RF_DTB7;
if(gpioa_pin_list != 0)
{
gpio_config.Pin = gpioa_pin_list;
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_C2GPIOA_CLK_ENABLE();
HAL_GPIO_Init(GPIOA, &gpio_config);
}
if(gpiob_pin_list != 0)
{
gpio_config.Pin = gpiob_pin_list;
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_C2GPIOB_CLK_ENABLE();
HAL_GPIO_Init(GPIOB, &gpio_config);
}
#else
STBY_DtbGpioaPinList = 0;
STBY_DtbGpiobPinList = 0;
#endif
/* USER CODE END APPD_BleDtbCfg */
return;
}
/*************************************************************
*
* WRAP FUNCTIONS
*
*************************************************************/
#if(CFG_DEBUG_TRACE != 0)
void DbgOutputInit( void )
{
/* USER CODE BEGIN DbgOutputInit */
#ifdef CFG_DEBUG_TRACE_UART
if (CFG_DEBUG_TRACE_UART == hw_lpuart1)
{
#if(CFG_HW_LPUART1_ENABLED == 1)
MX_LPUART1_UART_Init();
#endif
}
else if (CFG_DEBUG_TRACE_UART == hw_uart1)
{
#if(CFG_HW_USART1_ENABLED == 1)
MX_USART1_UART_Init();
#endif
}
#endif
/* USER CODE END DbgOutputInit */
return;
}
void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) )
{
/* USER CODE BEGIN DbgOutputTraces */
//HW_UART_Transmit_DMA(CFG_DEBUG_TRACE_UART, p_data, size, cb);
HAL_UART_Transmit(hw_uart1, p_data, size, HAL_MAX_DELAY);
/* USER CODE END DbgOutputTraces */
return;
}
#endif
@@ -1,588 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file app_entry.c
* @author MCD Application Team
* @brief Entry point of the application
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "app_common.h"
#include "main.h"
#include "app_entry.h"
#include "app_ble.h"
#include "ble.h"
#include "tl.h"
#include "stm32_seq.h"
#include "shci_tl.h"
#include "stm32_lpm.h"
#include "app_debug.h"
#include "dbg_trace.h"
#include "shci.h"
#include "otp.h"
/* Private includes -----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
extern RTC_HandleTypeDef hrtc;
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private defines -----------------------------------------------------------*/
#define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH*4U*DIVC((sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE), 4U))
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macros ------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t EvtPool[POOL_SIZE];
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t SystemCmdBuffer;
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t SystemSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U];
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t BleSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255];
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private functions prototypes-----------------------------------------------*/
static void Config_HSE(void);
static void Reset_Device(void);
#if (CFG_HW_RESET_BY_FW == 1)
static void Reset_IPCC(void);
static void Reset_BackupDomain(void);
#endif /* CFG_HW_RESET_BY_FW == 1*/
static void System_Init(void);
static void SystemPower_Config(void);
static void appe_Tl_Init(void);
static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status);
static void APPE_SysUserEvtRx(void * pPayload);
static void APPE_SysEvtReadyProcessing(void * pPayload);
static void APPE_SysEvtError(void * pPayload);
static void Init_Rtc(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Functions Definition ------------------------------------------------------*/
void MX_APPE_Config(void)
{
/**
* The OPTVERR flag is wrongly set at power on
* It shall be cleared before using any HAL_FLASH_xxx() api
*/
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
/**
* Reset some configurations so that the system behave in the same way
* when either out of nReset or Power On
*/
Reset_Device();
/* Configure HSE Tuning */
Config_HSE();
return;
}
void MX_APPE_Init(void)
{
System_Init(); /**< System initialization */
SystemPower_Config(); /**< Configure the system Power Mode */
HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */
/* USER CODE BEGIN APPE_Init_1 */
/* USER CODE END APPE_Init_1 */
appe_Tl_Init(); /* Initialize all transport layers */
/**
* From now, the application is waiting for the ready event (VS_HCI_C2_Ready)
* received on the system channel before starting the Stack
* This system event is received with APPE_SysUserEvtRx()
*/
/* USER CODE BEGIN APPE_Init_2 */
/* USER CODE END APPE_Init_2 */
return;
}
void Init_Smps(void)
{
#if (CFG_USE_SMPS != 0)
/**
* Configure and enable SMPS
*
* The SMPS configuration is not yet supported by CubeMx
* when SMPS output voltage is set to 1.4V, the RF output power is limited to 3.7dBm
* the SMPS output voltage shall be increased for higher RF output power
*/
LL_PWR_SMPS_SetStartupCurrent(LL_PWR_SMPS_STARTUP_CURRENT_80MA);
LL_PWR_SMPS_SetOutputVoltageLevel(LL_PWR_SMPS_OUTPUT_VOLTAGE_1V40);
LL_PWR_SMPS_Enable();
#endif /* CFG_USE_SMPS != 0 */
return;
}
void Init_Exti(void)
{
/* Enable IPCC(36), HSEM(38) wakeup interrupts on CPU1 */
LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_36 | LL_EXTI_LINE_38);
return;
}
/* USER CODE BEGIN FD */
/* USER CODE END FD */
/*************************************************************
*
* LOCAL FUNCTIONS
*
*************************************************************/
static void Reset_Device(void)
{
#if (CFG_HW_RESET_BY_FW == 1)
Reset_BackupDomain();
Reset_IPCC();
#endif /* CFG_HW_RESET_BY_FW == 1 */
return;
}
#if (CFG_HW_RESET_BY_FW == 1)
static void Reset_BackupDomain(void)
{
if ((LL_RCC_IsActiveFlag_PINRST() != FALSE) && (LL_RCC_IsActiveFlag_SFTRST() == FALSE))
{
HAL_PWR_EnableBkUpAccess(); /**< Enable access to the RTC registers */
/**
* Write twice the value to flush the APB-AHB bridge
* This bit shall be written in the register before writing the next one
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_BACKUPRESET_FORCE();
__HAL_RCC_BACKUPRESET_RELEASE();
}
return;
}
static void Reset_IPCC(void)
{
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC);
LL_C1_IPCC_ClearFlag_CHx(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C2_IPCC_ClearFlag_CHx(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C1_IPCC_DisableTransmitChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C2_IPCC_DisableTransmitChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C1_IPCC_DisableReceiveChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
LL_C2_IPCC_DisableReceiveChannel(
IPCC,
LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
| LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
return;
}
#endif /* CFG_HW_RESET_BY_FW == 1 */
static void Config_HSE(void)
{
OTP_ID0_t * p_otp;
/**
* Read HSE_Tuning from OTP
*/
p_otp = (OTP_ID0_t *) OTP_Read(0);
if (p_otp)
{
LL_RCC_HSE_SetCapacitorTuning(p_otp->hse_tuning);
}
return;
}
static void System_Init(void)
{
Init_Smps();
Init_Exti();
Init_Rtc();
return;
}
static void Init_Rtc(void)
{
/* Disable RTC registers write protection */
LL_RTC_DisableWriteProtection(RTC);
LL_RTC_WAKEUP_SetClock(RTC, CFG_RTC_WUCKSEL_DIVIDER);
/* Enable RTC registers write protection */
LL_RTC_EnableWriteProtection(RTC);
return;
}
/**
* @brief Configure the system for power optimization
*
* @note This API configures the system to be ready for low power mode
*
* @param None
* @retval None
*/
static void SystemPower_Config(void)
{
/**
* Select HSI as system clock source after Wake Up from Stop mode
*/
LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
/* Initialize low power manager */
UTIL_LPM_Init();
/* Initialize the CPU2 reset value before starting CPU2 with C2BOOT */
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
#if (CFG_USB_INTERFACE_ENABLE != 0)
/**
* Enable USB power
*/
HAL_PWREx_EnableVddUSB();
#endif /* CFG_USB_INTERFACE_ENABLE != 0 */
/**
* Active SRAM retention for standby support
*/
HAL_PWREx_EnableSRAMRetention();
return;
}
static void appe_Tl_Init(void)
{
TL_MM_Config_t tl_mm_config;
SHCI_TL_HciInitConf_t SHci_Tl_Init_Conf;
/**< Reference table initialization */
TL_Init();
/**< System channel initialization */
UTIL_SEQ_RegTask(1<< CFG_TASK_SYSTEM_HCI_ASYNCH_EVT_ID, UTIL_SEQ_RFU, shci_user_evt_proc);
SHci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&SystemCmdBuffer;
SHci_Tl_Init_Conf.StatusNotCallBack = APPE_SysStatusNot;
shci_init(APPE_SysUserEvtRx, (void*) &SHci_Tl_Init_Conf);
/**< Memory Manager channel initialization */
tl_mm_config.p_BleSpareEvtBuffer = BleSpareEvtBuffer;
tl_mm_config.p_SystemSpareEvtBuffer = SystemSpareEvtBuffer;
tl_mm_config.p_AsynchEvtPool = EvtPool;
tl_mm_config.AsynchEvtPoolSize = POOL_SIZE;
TL_MM_Init(&tl_mm_config);
TL_Enable();
return;
}
static void APPE_SysStatusNot(SHCI_TL_CmdStatus_t status)
{
UNUSED(status);
return;
}
/**
* The type of the payload for a system user event is tSHCI_UserEvtRxParam
* When the system event is both :
* - a ready event (subevtcode = SHCI_SUB_EVT_CODE_READY)
* - reported by the FUS (sysevt_ready_rsp == FUS_FW_RUNNING)
* The buffer shall not be released
* (eg ((tSHCI_UserEvtRxParam*)pPayload)->status shall be set to SHCI_TL_UserEventFlow_Disable)
* When the status is not filled, the buffer is released by default
*/
static void APPE_SysUserEvtRx(void * pPayload)
{
TL_AsynchEvt_t *p_sys_event;
WirelessFwInfo_t WirelessInfo;
p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
switch(p_sys_event->subevtcode)
{
case SHCI_SUB_EVT_CODE_READY:
/* Read the firmware version of both the wireless firmware and the FUS */
SHCI_GetWirelessFwInfo(&WirelessInfo);
APP_DBG_MSG("Wireless Firmware version %d.%d.%d\n", WirelessInfo.VersionMajor, WirelessInfo.VersionMinor, WirelessInfo.VersionSub);
APP_DBG_MSG("Wireless Firmware build %d\n", WirelessInfo.VersionReleaseType);
APP_DBG_MSG("FUS version %d.%d.%d\n", WirelessInfo.FusVersionMajor, WirelessInfo.FusVersionMinor, WirelessInfo.FusVersionSub);
APP_DBG_MSG(">>== SHCI_SUB_EVT_CODE_READY\n\r");
APPE_SysEvtReadyProcessing(pPayload);
break;
case SHCI_SUB_EVT_ERROR_NOTIF:
APP_DBG_MSG(">>== SHCI_SUB_EVT_ERROR_NOTIF \n\r");
APPE_SysEvtError(pPayload);
break;
case SHCI_SUB_EVT_BLE_NVM_RAM_UPDATE:
APP_DBG_MSG(">>== SHCI_SUB_EVT_BLE_NVM_RAM_UPDATE -- BLE NVM RAM HAS BEEN UPDATED BY CPU2 \n");
APP_DBG_MSG(" - StartAddress = %lx , Size = %ld\n",
((SHCI_C2_BleNvmRamUpdate_Evt_t*)p_sys_event->payload)->StartAddress,
((SHCI_C2_BleNvmRamUpdate_Evt_t*)p_sys_event->payload)->Size);
break;
case SHCI_SUB_EVT_NVM_START_WRITE:
APP_DBG_MSG("==>> SHCI_SUB_EVT_NVM_START_WRITE : NumberOfWords = %ld\n",
((SHCI_C2_NvmStartWrite_Evt_t*)p_sys_event->payload)->NumberOfWords);
break;
case SHCI_SUB_EVT_NVM_END_WRITE:
APP_DBG_MSG(">>== SHCI_SUB_EVT_NVM_END_WRITE\n\r");
break;
case SHCI_SUB_EVT_NVM_START_ERASE:
APP_DBG_MSG("==>>SHCI_SUB_EVT_NVM_START_ERASE : NumberOfSectors = %ld\n",
((SHCI_C2_NvmStartErase_Evt_t*)p_sys_event->payload)->NumberOfSectors);
break;
case SHCI_SUB_EVT_NVM_END_ERASE:
APP_DBG_MSG(">>== SHCI_SUB_EVT_NVM_END_ERASE\n\r");
break;
default:
break;
}
return;
}
/**
* @brief Notify a system error coming from the M0 firmware
* @param ErrorCode : errorCode detected by the M0 firmware
*
* @retval None
*/
static void APPE_SysEvtError(void * pPayload)
{
TL_AsynchEvt_t *p_sys_event;
SCHI_SystemErrCode_t *p_sys_error_code;
p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
p_sys_error_code = (SCHI_SystemErrCode_t*) p_sys_event->payload;
APP_DBG_MSG(">>== SHCI_SUB_EVT_ERROR_NOTIF WITH REASON %x \n\r",(*p_sys_error_code));
if ((*p_sys_error_code) == ERR_BLE_INIT)
{
/* Error during BLE stack initialization */
APP_DBG_MSG(">>== SHCI_SUB_EVT_ERROR_NOTIF WITH REASON - ERR_BLE_INIT \n");
}
else
{
APP_DBG_MSG(">>== SHCI_SUB_EVT_ERROR_NOTIF WITH REASON - BLE ERROR \n");
}
return;
}
static void APPE_SysEvtReadyProcessing(void * pPayload)
{
TL_AsynchEvt_t *p_sys_event;
SHCI_C2_Ready_Evt_t *p_sys_ready_event;
SHCI_C2_CONFIG_Cmd_Param_t config_param = {0};
uint32_t RevisionID=0;
uint32_t DeviceID=0;
p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
p_sys_ready_event = (SHCI_C2_Ready_Evt_t*) p_sys_event->payload;
if (p_sys_ready_event->sysevt_ready_rsp == WIRELESS_FW_RUNNING)
{
/**
* The wireless firmware is running on the CPU2
*/
APP_DBG_MSG(">>== WIRELESS_FW_RUNNING \n");
/* Traces channel initialization */
APPD_EnableCPU2();
/* Enable all events Notification */
config_param.PayloadCmdSize = SHCI_C2_CONFIG_PAYLOAD_CMD_SIZE;
config_param.EvtMask1 = SHCI_C2_CONFIG_EVTMASK1_BIT0_ERROR_NOTIF_ENABLE
+ SHCI_C2_CONFIG_EVTMASK1_BIT1_BLE_NVM_RAM_UPDATE_ENABLE
+ SHCI_C2_CONFIG_EVTMASK1_BIT2_THREAD_NVM_RAM_UPDATE_ENABLE
+ SHCI_C2_CONFIG_EVTMASK1_BIT3_NVM_START_WRITE_ENABLE
+ SHCI_C2_CONFIG_EVTMASK1_BIT4_NVM_END_WRITE_ENABLE
+ SHCI_C2_CONFIG_EVTMASK1_BIT5_NVM_START_ERASE_ENABLE
+ SHCI_C2_CONFIG_EVTMASK1_BIT6_NVM_END_ERASE_ENABLE;
/* Read revision identifier */
/**
* @brief Return the device revision identifier
* @note This field indicates the revision of the device.
* @rmtoll DBGMCU_IDCODE REV_ID LL_DBGMCU_GetRevisionID
* @retval Values between Min_Data=0x00 and Max_Data=0xFFFF
*/
RevisionID = LL_DBGMCU_GetRevisionID();
APP_DBG_MSG(">>== DBGMCU_GetRevisionID= %lx \n\r", RevisionID);
config_param.RevisionID = (uint16_t)RevisionID;
DeviceID = LL_DBGMCU_GetDeviceID();
APP_DBG_MSG(">>== DBGMCU_GetDeviceID= %lx \n\r", DeviceID);
config_param.DeviceID = (uint16_t)DeviceID;
(void)SHCI_C2_Config(&config_param);
APP_BLE_Init();
UTIL_LPM_SetOffMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE);
}
else if (p_sys_ready_event->sysevt_ready_rsp == FUS_FW_RUNNING)
{
/**
* The FUS firmware is running on the CPU2
* In the scope of this application, there should be no case when we get here
*/
APP_DBG_MSG(">>== SHCI_SUB_EVT_CODE_READY - FUS_FW_RUNNING \n\r");
/* The packet shall not be released as this is not supported by the FUS */
((tSHCI_UserEvtRxParam*)pPayload)->status = SHCI_TL_UserEventFlow_Disable;
}
else
{
APP_DBG_MSG(">>== SHCI_SUB_EVT_CODE_READY - UNEXPECTED CASE \n\r");
}
return;
}
/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */
/* USER CODE END FD_LOCAL_FUNCTIONS */
/*************************************************************
*
* WRAP FUNCTIONS
*
*************************************************************/
void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a freq to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += HAL_GetTickFreq();
}
while ((HAL_GetTick() - tickstart) < wait)
{
/************************************************************************************
* ENTER SLEEP MODE
***********************************************************************************/
LL_LPM_EnableSleep(); /**< Clear SLEEPDEEP bit of Cortex System Control Register */
/**
* This option is used to ensure that store operations are completed
*/
#if defined (__CC_ARM) || defined (__ARMCC_VERSION)
__force_stores();
#endif /* __ARMCC_VERSION */
__WFI();
}
}
void MX_APPE_Process(void)
{
/* USER CODE BEGIN MX_APPE_Process_1 */
/* USER CODE END MX_APPE_Process_1 */
UTIL_SEQ_Run(UTIL_SEQ_DEFAULT);
/* USER CODE BEGIN MX_APPE_Process_2 */
/* USER CODE END MX_APPE_Process_2 */
}
void UTIL_SEQ_Idle(void)
{
#if (CFG_LPM_SUPPORTED == 1)
UTIL_LPM_EnterLowPower();
#endif /* CFG_LPM_SUPPORTED == 1 */
return;
}
void shci_notify_asynch_evt(void* pdata)
{
UTIL_SEQ_SetTask(1<<CFG_TASK_SYSTEM_HCI_ASYNCH_EVT_ID, CFG_SCH_PRIO_0);
return;
}
void shci_cmd_resp_release(uint32_t flag)
{
UTIL_SEQ_SetEvt(1<< CFG_IDLEEVT_SYSTEM_HCI_CMD_EVT_RSP_ID);
return;
}
void shci_cmd_resp_wait(uint32_t timeout)
{
UTIL_SEQ_WaitEvt(1<< CFG_IDLEEVT_SYSTEM_HCI_CMD_EVT_RSP_ID);
return;
}
/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
/* USER CODE END FD_WRAP_FUNCTIONS */
@@ -1,59 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.c
* @brief This file provides code for the configuration
* of all the requested memory to memory DMA transfers.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure DMA */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Enable DMA controller clock
*/
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMAMUX1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
@@ -1,69 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file gpio.c
* @brief This file provides code for the configuration
* of all used GPIO pins.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "gpio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure GPIO */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/** Configure pins
PA8 ------> RCC_MCO
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, LED4_Pin|LED5_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : PA8 */
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : LED4_Pin LED5_Pin */
GPIO_InitStruct.Pin = LED4_Pin|LED5_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
@@ -1,888 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file hw_timerserver.c
* @author MCD Application Team
* @brief Hardware timerserver source file for STM32WPAN Middleware.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "app_common.h"
#include "hw_conf.h"
/* Private typedef -----------------------------------------------------------*/
typedef enum
{
TimerID_Free,
TimerID_Created,
TimerID_Running
}TimerIDStatus_t;
typedef enum
{
SSR_Read_Requested,
SSR_Read_Not_Requested
}RequestReadSSR_t;
typedef enum
{
WakeupTimerValue_Overpassed,
WakeupTimerValue_LargeEnough
}WakeupTimerLimitation_Status_t;
typedef struct
{
HW_TS_pTimerCb_t pTimerCallBack;
uint32_t CounterInit;
uint32_t CountLeft;
TimerIDStatus_t TimerIDStatus;
HW_TS_Mode_t TimerMode;
uint32_t TimerProcessID;
uint8_t PreviousID;
uint8_t NextID;
}TimerContext_t;
/* Private defines -----------------------------------------------------------*/
#define SSR_FORBIDDEN_VALUE 0xFFFFFFFF
#define TIMER_LIST_EMPTY 0xFFFF
/* Private macros ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/**
* START of Section TIMERSERVER_CONTEXT
*/
static volatile TimerContext_t aTimerContext[CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER];
static volatile uint8_t CurrentRunningTimerID;
static volatile uint8_t PreviousRunningTimerID;
static volatile uint32_t SSRValueOnLastSetup;
static volatile WakeupTimerLimitation_Status_t WakeupTimerLimitation;
/**
* END of Section TIMERSERVER_CONTEXT
*/
static uint8_t WakeupTimerDivider;
static uint8_t AsynchPrescalerUserConfig;
static uint16_t SynchPrescalerUserConfig;
static volatile uint16_t MaxWakeupTimerSetup;
/* Global variables ----------------------------------------------------------*/
extern RTC_HandleTypeDef hrtc;
/* Private function prototypes -----------------------------------------------*/
static void RestartWakeupCounter(uint16_t Value);
static uint16_t ReturnTimeElapsed(void);
static void RescheduleTimerList(void);
static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR);
static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID);
static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID);
static uint16_t linkTimer(uint8_t TimerID);
static uint32_t ReadRtcSsrValue(void);
__weak void HW_TS_RTC_CountUpdated_AppNot(void);
/* Functions Definition ------------------------------------------------------*/
/**
* @brief Read the RTC_SSR value
* As described in the reference manual, the RTC_SSR shall be read twice to ensure
* reliability of the value
* @param None
* @retval SSR value read
*/
static uint32_t ReadRtcSsrValue(void)
{
uint32_t first_read;
uint32_t second_read;
first_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
while(first_read != second_read)
{
first_read = second_read;
second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
}
return second_read;
}
/**
* @brief Insert a Timer in the list after the Timer ID specified
* @param TimerID: The ID of the Timer
* @param RefTimerID: The ID of the Timer to be linked after
* @retval None
*/
static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID)
{
uint8_t next_id;
next_id = aTimerContext[RefTimerID].NextID;
if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
{
aTimerContext[next_id].PreviousID = TimerID;
}
aTimerContext[TimerID].NextID = next_id;
aTimerContext[TimerID].PreviousID = RefTimerID ;
aTimerContext[RefTimerID].NextID = TimerID;
return;
}
/**
* @brief Insert a Timer in the list before the ID specified
* @param TimerID: The ID of the Timer
* @param RefTimerID: The ID of the Timer to be linked before
* @retval None
*/
static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID)
{
uint8_t previous_id;
if(RefTimerID != CurrentRunningTimerID)
{
previous_id = aTimerContext[RefTimerID].PreviousID;
aTimerContext[previous_id].NextID = TimerID;
aTimerContext[TimerID].NextID = RefTimerID;
aTimerContext[TimerID].PreviousID = previous_id ;
aTimerContext[RefTimerID].PreviousID = TimerID;
}
else
{
aTimerContext[TimerID].NextID = RefTimerID;
aTimerContext[RefTimerID].PreviousID = TimerID;
}
return;
}
/**
* @brief Insert a Timer in the list
* @param TimerID: The ID of the Timer
* @retval None
*/
static uint16_t linkTimer(uint8_t TimerID)
{
uint32_t time_left;
uint16_t time_elapsed;
uint8_t timer_id_lookup;
uint8_t next_id;
if(CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
{
/**
* No timer in the list
*/
PreviousRunningTimerID = CurrentRunningTimerID;
CurrentRunningTimerID = TimerID;
aTimerContext[TimerID].NextID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER;
SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
time_elapsed = 0;
}
else
{
time_elapsed = ReturnTimeElapsed();
/**
* update count of the timer to be linked
*/
aTimerContext[TimerID].CountLeft += time_elapsed;
time_left = aTimerContext[TimerID].CountLeft;
/**
* Search for index where the new timer shall be linked
*/
if(aTimerContext[CurrentRunningTimerID].CountLeft <= time_left)
{
/**
* Search for the ID after the first one
*/
timer_id_lookup = CurrentRunningTimerID;
next_id = aTimerContext[timer_id_lookup].NextID;
while((next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[next_id].CountLeft <= time_left))
{
timer_id_lookup = aTimerContext[timer_id_lookup].NextID;
next_id = aTimerContext[timer_id_lookup].NextID;
}
/**
* Link after the ID
*/
LinkTimerAfter(TimerID, timer_id_lookup);
}
else
{
/**
* Link before the first ID
*/
LinkTimerBefore(TimerID, CurrentRunningTimerID);
PreviousRunningTimerID = CurrentRunningTimerID;
CurrentRunningTimerID = TimerID;
}
}
return time_elapsed;
}
/**
* @brief Remove a Timer from the list
* @param TimerID: The ID of the Timer
* @param RequestReadSSR: Request to read the SSR register or not
* @retval None
*/
static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR)
{
uint8_t previous_id;
uint8_t next_id;
if(TimerID == CurrentRunningTimerID)
{
PreviousRunningTimerID = CurrentRunningTimerID;
CurrentRunningTimerID = aTimerContext[TimerID].NextID;
}
else
{
previous_id = aTimerContext[TimerID].PreviousID;
next_id = aTimerContext[TimerID].NextID;
aTimerContext[previous_id].NextID = aTimerContext[TimerID].NextID;
if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
{
aTimerContext[next_id].PreviousID = aTimerContext[TimerID].PreviousID;
}
}
/**
* Timer is out of the list
*/
aTimerContext[TimerID].TimerIDStatus = TimerID_Created;
if((CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (RequestReadSSR == SSR_Read_Requested))
{
SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
}
return;
}
/**
* @brief Return the number of ticks counted by the wakeuptimer since it has been started
* @note The API is reading the SSR register to get how many ticks have been counted
* since the time the timer has been started
* @param None
* @retval Time expired in Ticks
*/
static uint16_t ReturnTimeElapsed(void)
{
uint32_t return_value;
uint32_t wrap_counter;
if(SSRValueOnLastSetup != SSR_FORBIDDEN_VALUE)
{
return_value = ReadRtcSsrValue(); /**< Read SSR register first */
if (SSRValueOnLastSetup >= return_value)
{
return_value = SSRValueOnLastSetup - return_value;
}
else
{
wrap_counter = SynchPrescalerUserConfig - return_value;
return_value = SSRValueOnLastSetup + wrap_counter;
}
/**
* At this stage, ReturnValue holds the number of ticks counted by SSR
* Need to translate in number of ticks counted by the Wakeuptimer
*/
return_value = return_value*AsynchPrescalerUserConfig;
return_value = return_value >> WakeupTimerDivider;
}
else
{
return_value = 0;
}
return (uint16_t)return_value;
}
/**
* @brief Set the wakeup counter
* @note The API is writing the counter value so that the value is decreased by one to cope with the fact
* the interrupt is generated with 1 extra clock cycle (See RefManuel)
* It assumes all condition are met to be allowed to write the wakeup counter
* @param Value: Value to be written in the counter
* @retval None
*/
static void RestartWakeupCounter(uint16_t Value)
{
/**
* The wakeuptimer has been disabled in the calling function to reduce the time to poll the WUTWF
* FLAG when the new value will have to be written
* __HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc);
*/
if(Value == 0)
{
SSRValueOnLastSetup = ReadRtcSsrValue();
/**
* Simulate that the Timer expired
*/
HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID);
}
else
{
if((Value > 1) ||(WakeupTimerDivider != 1))
{
Value -= 1;
}
while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTWF) == RESET);
/**
* make sure to clear the flags after checking the WUTWF.
* It takes 2 RTCCLK between the time the WUTE bit is disabled and the
* time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
* Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
* due to the autoreload feature
*/
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
MODIFY_REG(RTC->WUTR, RTC_WUTR_WUT, Value);
/**
* Update the value here after the WUTWF polling that may take some time
*/
SSRValueOnLastSetup = ReadRtcSsrValue();
__HAL_RTC_WAKEUPTIMER_ENABLE(&hrtc); /**< Enable the Wakeup Timer */
HW_TS_RTC_CountUpdated_AppNot();
}
return ;
}
/**
* @brief Reschedule the list of timer
* @note 1) Update the count left for each timer in the list
* 2) Setup the wakeuptimer
* @param None
* @retval None
*/
static void RescheduleTimerList(void)
{
uint8_t localTimerID;
uint32_t timecountleft;
uint16_t wakeup_timer_value;
uint16_t time_elapsed;
/**
* The wakeuptimer is disabled now to reduce the time to poll the WUTWF
* FLAG when the new value will have to be written
*/
if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
{
/**
* Wait for the flag to be back to 0 when the wakeup timer is enabled
*/
while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTWF) == SET);
}
__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc); /**< Disable the Wakeup Timer */
localTimerID = CurrentRunningTimerID;
/**
* Calculate what will be the value to write in the wakeuptimer
*/
timecountleft = aTimerContext[localTimerID].CountLeft;
/**
* Read how much has been counted
*/
time_elapsed = ReturnTimeElapsed();
if(timecountleft < time_elapsed )
{
/**
* There is no tick left to count
*/
wakeup_timer_value = 0;
WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
}
else
{
if(timecountleft > (time_elapsed + MaxWakeupTimerSetup))
{
/**
* The number of tick left is greater than the Wakeuptimer maximum value
*/
wakeup_timer_value = MaxWakeupTimerSetup;
WakeupTimerLimitation = WakeupTimerValue_Overpassed;
}
else
{
wakeup_timer_value = timecountleft - time_elapsed;
WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
}
}
/**
* update ticks left to be counted for each timer
*/
while(localTimerID != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
{
if (aTimerContext[localTimerID].CountLeft < time_elapsed)
{
aTimerContext[localTimerID].CountLeft = 0;
}
else
{
aTimerContext[localTimerID].CountLeft -= time_elapsed;
}
localTimerID = aTimerContext[localTimerID].NextID;
}
/**
* Write next count
*/
RestartWakeupCounter(wakeup_timer_value);
return ;
}
/* Public functions ----------------------------------------------------------*/
/**
* For all public interface except that may need write access to the RTC, the RTC
* shall be unlock at the beginning and locked at the output
* In order to ease maintainability, the unlock is done at the top and the lock at then end
* in case some new implementation is coming in the future
*/
void HW_TS_RTC_Wakeup_Handler(void)
{
HW_TS_pTimerCb_t ptimer_callback;
uint32_t timer_process_id;
uint8_t local_current_running_timer_id;
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
uint32_t primask_bit;
#endif
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
#endif
/* Disable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_DISABLE( &hrtc );
/**
* Disable the Wakeup Timer
* This may speed up a bit the processing to wait the timer to be disabled
* The timer is still counting 2 RTCCLK
*/
__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc);
local_current_running_timer_id = CurrentRunningTimerID;
if(aTimerContext[local_current_running_timer_id].TimerIDStatus == TimerID_Running)
{
ptimer_callback = aTimerContext[local_current_running_timer_id].pTimerCallBack;
timer_process_id = aTimerContext[local_current_running_timer_id].TimerProcessID;
/**
* It should be good to check whether the TimeElapsed is greater or not than the tick left to be counted
* However, due to the inaccuracy of the reading of the time elapsed, it may return there is 1 tick
* to be left whereas the count is over
* A more secure implementation has been done with a flag to state whereas the full count has been written
* in the wakeuptimer or not
*/
if(WakeupTimerLimitation != WakeupTimerValue_Overpassed)
{
if(aTimerContext[local_current_running_timer_id].TimerMode == hw_ts_Repeated)
{
UnlinkTimer(local_current_running_timer_id, SSR_Read_Not_Requested);
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
#endif
HW_TS_Start(local_current_running_timer_id, aTimerContext[local_current_running_timer_id].CounterInit);
/* Disable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_DISABLE( &hrtc );
}
else
{
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
#endif
HW_TS_Stop(local_current_running_timer_id);
/* Disable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_DISABLE( &hrtc );
}
HW_TS_RTC_Int_AppNot(timer_process_id, local_current_running_timer_id, ptimer_callback);
}
else
{
RescheduleTimerList();
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
#endif
}
}
else
{
/**
* We should never end up in this case
* However, if due to any bug in the timer server this is the case, the mistake may not impact the user.
* We could just clean the interrupt flag and get out from this unexpected interrupt
*/
while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTWF) == RESET);
/**
* make sure to clear the flags after checking the WUTWF.
* It takes 2 RTCCLK between the time the WUTE bit is disabled and the
* time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
* Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
* due to the autoreload feature
*/
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
#endif
}
/* Enable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_ENABLE( &hrtc );
return;
}
void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *phrtc)
{
uint8_t loop;
uint32_t localmaxwakeuptimersetup;
/* Disable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_DISABLE( &hrtc );
SET_BIT(RTC->CR, RTC_CR_BYPSHAD);
/**
* Readout the user config
*/
WakeupTimerDivider = (4 - ((uint32_t)(READ_BIT(RTC->CR, RTC_CR_WUCKSEL))));
AsynchPrescalerUserConfig = (uint8_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_A) >> (uint32_t)POSITION_VAL(RTC_PRER_PREDIV_A)) + 1;
SynchPrescalerUserConfig = (uint16_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_S)) + 1;
/**
* Margin is taken to avoid wrong calculation when the wrap around is there and some
* application interrupts may have delayed the reading
*/
localmaxwakeuptimersetup = ((((SynchPrescalerUserConfig - 1)*AsynchPrescalerUserConfig) - CFG_HW_TS_RTC_HANDLER_MAX_DELAY) >> WakeupTimerDivider);
if(localmaxwakeuptimersetup >= 0xFFFF)
{
MaxWakeupTimerSetup = 0xFFFF;
}
else
{
MaxWakeupTimerSetup = (uint16_t)localmaxwakeuptimersetup;
}
/**
* Configure EXTI module
*/
LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT);
LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT);
if(TimerInitMode == hw_ts_InitMode_Full)
{
WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
/**
* Initialize the timer server
*/
for(loop = 0; loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; loop++)
{
aTimerContext[loop].TimerIDStatus = TimerID_Free;
}
CurrentRunningTimerID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; /**< Set ID to non valid value */
__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc); /**< Disable the Wakeup Timer */
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
__HAL_RTC_WAKEUPTIMER_ENABLE_IT(&hrtc, RTC_IT_WUT); /**< Enable interrupt in RTC module */
}
else
{
if(__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTF) != RESET)
{
/**
* Simulate that the Timer expired
*/
HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID);
}
}
/* Enable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_ENABLE( &hrtc );
HAL_NVIC_SetPriority(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO); /**< Set NVIC priority */
HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
return;
}
HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pftimeout_handler)
{
HW_TS_ReturnStatus_t localreturnstatus;
uint8_t loop = 0;
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
uint32_t primask_bit;
#endif
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
#endif
while((loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[loop].TimerIDStatus != TimerID_Free))
{
loop++;
}
if(loop != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
{
aTimerContext[loop].TimerIDStatus = TimerID_Created;
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
#endif
aTimerContext[loop].TimerProcessID = TimerProcessID;
aTimerContext[loop].TimerMode = TimerMode;
aTimerContext[loop].pTimerCallBack = pftimeout_handler;
*pTimerId = loop;
localreturnstatus = hw_ts_Successful;
}
else
{
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
#endif
localreturnstatus = hw_ts_Failed;
}
return(localreturnstatus);
}
void HW_TS_Delete(uint8_t timer_id)
{
HW_TS_Stop(timer_id);
aTimerContext[timer_id].TimerIDStatus = TimerID_Free; /**< release ID */
return;
}
void HW_TS_Stop(uint8_t timer_id)
{
uint8_t localcurrentrunningtimerid;
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
uint32_t primask_bit;
#endif
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
#endif
HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */
/* Disable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_DISABLE( &hrtc );
if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running)
{
UnlinkTimer(timer_id, SSR_Read_Requested);
localcurrentrunningtimerid = CurrentRunningTimerID;
if(localcurrentrunningtimerid == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
{
/**
* List is empty
*/
/**
* Disable the timer
*/
if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
{
/**
* Wait for the flag to be back to 0 when the wakeup timer is enabled
*/
while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTWF) == SET);
}
__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc); /**< Disable the Wakeup Timer */
while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTWF) == RESET);
/**
* make sure to clear the flags after checking the WUTWF.
* It takes 2 RTCCLK between the time the WUTE bit is disabled and the
* time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
* Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
* due to the autoreload feature
*/
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
__HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
}
else if(PreviousRunningTimerID != localcurrentrunningtimerid)
{
RescheduleTimerList();
}
}
/* Enable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_ENABLE( &hrtc );
HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
#endif
return;
}
void HW_TS_Start(uint8_t timer_id, uint32_t timeout_ticks)
{
uint16_t time_elapsed;
uint8_t localcurrentrunningtimerid;
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
uint32_t primask_bit;
#endif
if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running)
{
HW_TS_Stop( timer_id );
}
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
#endif
HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */
/* Disable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_DISABLE( &hrtc );
aTimerContext[timer_id].TimerIDStatus = TimerID_Running;
aTimerContext[timer_id].CountLeft = timeout_ticks;
aTimerContext[timer_id].CounterInit = timeout_ticks;
time_elapsed = linkTimer(timer_id);
localcurrentrunningtimerid = CurrentRunningTimerID;
if(PreviousRunningTimerID != localcurrentrunningtimerid)
{
RescheduleTimerList();
}
else
{
aTimerContext[timer_id].CountLeft -= time_elapsed;
}
/* Enable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_ENABLE( &hrtc );
HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
#endif
return;
}
uint16_t HW_TS_RTC_ReadLeftTicksToCount(void)
{
uint32_t primask_bit;
uint16_t return_value, auro_reload_value, elapsed_time_value;
primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
__disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
{
auro_reload_value = (uint32_t)(READ_BIT(RTC->WUTR, RTC_WUTR_WUT));
elapsed_time_value = ReturnTimeElapsed();
if(auro_reload_value > elapsed_time_value)
{
return_value = auro_reload_value - elapsed_time_value;
}
else
{
return_value = 0;
}
}
else
{
return_value = TIMER_LIST_EMPTY;
}
__set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
return (return_value);
}
__weak void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack)
{
pTimerCallBack();
return;
}
@@ -1,317 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file Src/hw_uart.c
* @author MCD Application Team
* @brief HW UART source file for STM32WPAN Middleware.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "app_common.h"
#include "hw_conf.h"
#if (CFG_HW_LPUART1_ENABLED == 1)
extern UART_HandleTypeDef hlpuart1;
#endif
#if (CFG_HW_USART1_ENABLED == 1)
extern UART_HandleTypeDef huart1;
#endif
/* Macros --------------------------------------------------------------------*/
#define HW_UART_RX_IT(__HANDLE__, __USART_BASE__) \
do{ \
HW_##__HANDLE__##RxCb = cb; \
(__HANDLE__).Instance = (__USART_BASE__); \
HAL_UART_Receive_IT(&(__HANDLE__), p_data, size); \
} while(0)
#define HW_UART_TX_IT(__HANDLE__, __USART_BASE__) \
do{ \
HW_##__HANDLE__##TxCb = cb; \
(__HANDLE__).Instance = (__USART_BASE__); \
HAL_UART_Transmit_IT(&(__HANDLE__), p_data, size); \
} while(0)
#define HW_UART_TX(__HANDLE__, __USART_BASE__) \
do{ \
(__HANDLE__).Instance = (__USART_BASE__); \
hal_status = HAL_UART_Transmit(&(__HANDLE__), p_data, size, timeout); \
} while(0)
/* Variables -----------------------------------------------------------------*/
#if (CFG_HW_USART1_ENABLED == 1)
#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1)
DMA_HandleTypeDef HW_hdma_huart1_tx ={0};
#endif
void (*HW_huart1RxCb)(void);
void (*HW_huart1TxCb)(void);
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1)
DMA_HandleTypeDef HW_hdma_hlpuart1_tx ={0};
#endif
void (*HW_hlpuart1RxCb)(void);
void (*HW_hlpuart1TxCb)(void);
#endif
void HW_UART_Receive_IT(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*cb)(void))
{
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HW_UART_RX_IT(huart1, USART1);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HW_UART_RX_IT(hlpuart1, LPUART1);
break;
#endif
default:
break;
}
return;
}
void HW_UART_Transmit_IT(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*cb)(void))
{
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HW_UART_TX_IT(huart1, USART1);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HW_UART_TX_IT(hlpuart1, LPUART1);
break;
#endif
default:
break;
}
return;
}
hw_status_t HW_UART_Transmit(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, uint32_t timeout)
{
HAL_StatusTypeDef hal_status = HAL_OK;
hw_status_t hw_status = hw_uart_ok;
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HW_UART_TX(huart1, USART1);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HW_UART_TX(hlpuart1, LPUART1);
break;
#endif
default:
break;
}
switch (hal_status)
{
case HAL_OK:
hw_status = hw_uart_ok;
break;
case HAL_ERROR:
hw_status = hw_uart_error;
break;
case HAL_BUSY:
hw_status = hw_uart_busy;
break;
case HAL_TIMEOUT:
hw_status = hw_uart_to;
break;
default:
break;
}
return hw_status;
}
hw_status_t HW_UART_Transmit_DMA(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*cb)(void))
{
HAL_StatusTypeDef hal_status = HAL_OK;
hw_status_t hw_status = hw_uart_ok;
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HW_huart1TxCb = cb;
huart1.Instance = USART1;
hal_status = HAL_UART_Transmit_DMA(&huart1, p_data, size);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HW_hlpuart1TxCb = cb;
hlpuart1.Instance = LPUART1;
hal_status = HAL_UART_Transmit_DMA(&hlpuart1, p_data, size);
break;
#endif
default:
break;
}
switch (hal_status)
{
case HAL_OK:
hw_status = hw_uart_ok;
break;
case HAL_ERROR:
hw_status = hw_uart_error;
break;
case HAL_BUSY:
hw_status = hw_uart_busy;
break;
case HAL_TIMEOUT:
hw_status = hw_uart_to;
break;
default:
break;
}
return hw_status;
}
void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id)
{
switch (hw_uart_id)
{
#if (CFG_HW_USART1_ENABLED == 1)
case hw_uart1:
HAL_UART_IRQHandler(&huart1);
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case hw_lpuart1:
HAL_UART_IRQHandler(&hlpuart1);
break;
#endif
default:
break;
}
return;
}
void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id)
{
switch (hw_uart_id)
{
#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1)
case hw_uart1:
HAL_DMA_IRQHandler(huart1.hdmatx);
break;
#endif
#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1)
case hw_lpuart1:
HAL_DMA_IRQHandler(hlpuart1.hdmatx);
break;
#endif
default:
break;
}
return;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
switch ((uint32_t)huart->Instance)
{
#if (CFG_HW_USART1_ENABLED == 1)
case (uint32_t)USART1:
if(HW_huart1RxCb)
{
HW_huart1RxCb();
}
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case (uint32_t)LPUART1:
if(HW_hlpuart1RxCb)
{
HW_hlpuart1RxCb();
}
break;
#endif
default:
break;
}
return;
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
switch ((uint32_t)huart->Instance)
{
#if (CFG_HW_USART1_ENABLED == 1)
case (uint32_t)USART1:
if(HW_huart1TxCb)
{
HW_huart1TxCb();
}
break;
#endif
#if (CFG_HW_LPUART1_ENABLED == 1)
case (uint32_t)LPUART1:
if(HW_hlpuart1TxCb)
{
HW_hlpuart1TxCb();
}
break;
#endif
default:
break;
}
return;
}
@@ -1,96 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file ipcc.c
* @brief This file provides code for the configuration
* of the IPCC instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "ipcc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
IPCC_HandleTypeDef hipcc;
/* IPCC init function */
void MX_IPCC_Init(void)
{
/* USER CODE BEGIN IPCC_Init 0 */
/* USER CODE END IPCC_Init 0 */
/* USER CODE BEGIN IPCC_Init 1 */
/* USER CODE END IPCC_Init 1 */
hipcc.Instance = IPCC;
if (HAL_IPCC_Init(&hipcc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN IPCC_Init 2 */
/* USER CODE END IPCC_Init 2 */
}
void HAL_IPCC_MspInit(IPCC_HandleTypeDef* ipccHandle)
{
if(ipccHandle->Instance==IPCC)
{
/* USER CODE BEGIN IPCC_MspInit 0 */
/* USER CODE END IPCC_MspInit 0 */
/* IPCC clock enable */
__HAL_RCC_IPCC_CLK_ENABLE();
/* IPCC interrupt Init */
HAL_NVIC_SetPriority(IPCC_C1_RX_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(IPCC_C1_RX_IRQn);
HAL_NVIC_SetPriority(IPCC_C1_TX_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(IPCC_C1_TX_IRQn);
/* USER CODE BEGIN IPCC_MspInit 1 */
/* USER CODE END IPCC_MspInit 1 */
}
}
void HAL_IPCC_MspDeInit(IPCC_HandleTypeDef* ipccHandle)
{
if(ipccHandle->Instance==IPCC)
{
/* USER CODE BEGIN IPCC_MspDeInit 0 */
/* USER CODE END IPCC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_IPCC_CLK_DISABLE();
/* IPCC interrupt Deinit */
HAL_NVIC_DisableIRQ(IPCC_C1_RX_IRQn);
HAL_NVIC_DisableIRQ(IPCC_C1_TX_IRQn);
/* USER CODE BEGIN IPCC_MspDeInit 1 */
/* USER CODE END IPCC_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
-263
View File
@@ -1,263 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "main.h"
#include "dma.h"
#include "ipcc.h"
#include "rtc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdbool.h>
/* 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 */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
volatile bool uart_rx_busy = false;
volatile bool uart_tx_busy = false;
uint8_t uart_rx_data[1];
volatile bool queue_send = false;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
//if (uart_rx_data[0] == 'T') {
HAL_GPIO_TogglePin(GPIOB, LED4_Pin | LED5_Pin);
//}
uart_rx_busy = false;
}
void HAL_UART_TXCpltCallback(UART_HandleTypeDef *huart) {
HAL_GPIO_TogglePin(GPIOB, LED5_Pin);
uart_tx_busy = false;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM2) {
HAL_GPIO_TogglePin(GPIOB, LED4_Pin);
queue_send = true;
}
}
/* 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();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* IPCC initialisation */
MX_IPCC_Init();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_RTC_Init();
MX_USART1_UART_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_TIM_Base_Start_IT(&htim2);
uint8_t uart_tx_data[1] = {'T'};
while (1)
{
if (!uart_rx_busy) {
HAL_UART_Receive_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
uart_rx_busy = true;
}
if (queue_send && (!uart_tx_busy)) {
uart_tx_busy = true;
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
}
/* 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 LSE Drive Capability
*/
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_MEDIUMHIGH);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE
|RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
RCC_OscInitStruct.PLL.PLLN = 8;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4|RCC_CLOCKTYPE_HCLK2
|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_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV2;
RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_8);
}
/**
* @brief Peripherals Common Clock Configuration
* @retval None
*/
void PeriphCommonClock_Config(void)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS;
PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSI;
PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN Smps */
/* USER CODE END Smps */
}
/* 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 */
-47
View File
@@ -1,47 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file rf.c
* @brief This file provides code for the configuration
* of the RF instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "rf.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* RF init function */
void MX_RF_Init(void)
{
/* USER CODE BEGIN RF_Init 0 */
/* USER CODE END RF_Init 0 */
/* USER CODE BEGIN RF_Init 1 */
/* USER CODE END RF_Init 1 */
/* USER CODE BEGIN RF_Init 2 */
/* USER CODE END RF_Init 2 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
-108
View File
@@ -1,108 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file rtc.c
* @brief This file provides code for the configuration
* of the RTC instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "rtc.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
RTC_HandleTypeDef hrtc;
/* RTC init function */
void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
/* USER CODE BEGIN RTC_Init 1 */
/* USER CODE END RTC_Init 1 */
/** Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RTC_Init 2 */
/* USER CODE END RTC_Init 2 */
}
void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* RTC clock enable */
__HAL_RCC_RTC_ENABLE();
__HAL_RCC_RTCAPB_CLK_ENABLE();
/* USER CODE BEGIN RTC_MspInit 1 */
/* USER CODE END RTC_MspInit 1 */
}
}
void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
{
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspDeInit 0 */
/* USER CODE END RTC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_RTC_DISABLE();
__HAL_RCC_RTCAPB_CLK_DISABLE();
/* USER CODE BEGIN RTC_MspDeInit 1 */
/* USER CODE END RTC_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
@@ -1,247 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file standby.c
* @author MCD Application Team
* @brief Specific code for standby low power mode
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "main.h"
#include "app_entry.h"
#include "app_common.h"
#include "app_debug.h"
#include "standby.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 */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
uint32_t STBY_BackupMSP;
uint32_t STBY_BackupIpccC1MR;
uint32_t STBY_BackupVTOR;
uint32_t STBY_BootStatus;
uint16_t STBY_DebugGpioaPinList = UINT16_MAX;
uint16_t STBY_DebugGpiobPinList = UINT16_MAX;
uint16_t STBY_DebugGpiocPinList = UINT16_MAX;
uint16_t STBY_DtbGpioaPinList = UINT16_MAX;
uint16_t STBY_DtbGpiobPinList = UINT16_MAX;
extern RTC_HandleTypeDef hrtc;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
static void STBY_TriggerIT(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*******************************************************************************
* This part may be updated by the user
******************************************************************************/
void STBY_AppHwSave(void)
{
/* In this function HW parameters lost in standby can de saved.
All RAM memory is in retention */
/* USER CODE BEGIN STBY_AppHwSave_1 */
/* USER CODE END STBY_AppHwSave_1 */
return;
}
void STBY_AppHwRestore(void)
{
/* USER CODE BEGIN STBY_AppHwRestore_1 */
/* USER CODE END STBY_AppHwRestore_1 */
HAL_Init();
HAL_ResumeTick();
/* In this user section add MX init functions present in main.c, except MX_RTC_Init() */
/* USER CODE BEGIN STBY_AppHwRestore_2 */
/* USER CODE END STBY_AppHwRestore_2 */
STBY_TriggerIT();
return;
}
/*******************************************************************************
* Do not update code from this limit.
******************************************************************************/
void STBY_SysHwSave(void)
{
STBY_BackupIpccC1MR = READ_REG(IPCC->C1MR);
STBY_BackupVTOR = SCB->VTOR;
/* USER CODE BEGIN STBY_SysHwSave_1 */
/* USER CODE END STBY_SysHwSave_1 */
return;
}
void STBY_SysHwRestore(void)
{
/* USER CODE BEGIN STBY_SysHwRestore_1 */
/* USER CODE END STBY_SysHwRestore_1 */
APPD_Init();
Init_Smps();
Init_Exti();
HAL_Init();
WRITE_REG(SCB->VTOR, STBY_BackupVTOR);
HW_IPCC_Init();
WRITE_REG(IPCC->C1MR, STBY_BackupIpccC1MR);
if( !LL_HSEM_1StepLock( HSEM, CFG_HW_RCC_SEMID ) )
{
LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
LL_HSEM_ReleaseLock( HSEM, CFG_HW_RCC_SEMID, 0 );
}
LL_HSEM_ReleaseLock( HSEM, CFG_HW_PWR_STANDBY_SEMID, 0 );
HW_TS_Init(hw_ts_InitMode_Limited, &hrtc);
LL_PWR_EnableSRAM2Retention();
/* USER CODE BEGIN STBY_SysHwRestore_2 */
/* USER CODE END STBY_SysHwRestore_2 */
return;
}
uint32_t STBY_BootManager(void)
{
#if ( CFG_LPM_STANDBY_SUPPORTED != 0 )
__HAL_RCC_HSEM_CLK_ENABLE();
while( LL_HSEM_1StepLock( HSEM, CFG_HW_PWR_STANDBY_SEMID ) );
/* If a reset other than standby occurs, perform a full reset cycle */
if( (LL_RCC_IsActiveFlag_IWDGRST() != FALSE) ||
(LL_RCC_IsActiveFlag_WWDGRST() != FALSE) ||
(LL_RCC_IsActiveFlag_BORRST() != FALSE) ||
(LL_RCC_IsActiveFlag_LPWRRST() != FALSE) ||
(LL_RCC_IsActiveFlag_OBLRST() != FALSE) ||
(LL_RCC_IsActiveFlag_PINRST() != FALSE) ||
(LL_RCC_IsActiveFlag_SFTRST() != FALSE) )
{
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
}
if( __HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET )
{
__disable_irq( );
STBY_BootStatus = 1;
}else{
STBY_BootStatus = 0;
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_C2SB);
LL_HSEM_ReleaseLock( HSEM, CFG_HW_PWR_STANDBY_SEMID, 0 );
}
#else
STBY_BootStatus = 0;
#endif
return STBY_BootStatus;
}
static void STBY_TriggerIT(void)
{
/* If system has been woken-up by an RTC alarm,
* a software event must be generated to trigger the IT.
* NVIC and EXTI must be reconfigured properly before triggering the event.
*/
if((__HAL_RTC_ALARM_GET_FLAG((RTC_HandleTypeDef *)&hrtc, RTC_FLAG_ALRAF) != 0) ||
(__HAL_RTC_ALARM_GET_FLAG((RTC_HandleTypeDef *)&hrtc, RTC_FLAG_ALRBF) != 0) )
{
__HAL_RTC_ALARM_EXTI_GENERATE_SWIT();
}
/* If system has been woken-up by a wake up pin,
* a software event must be generated to trigger the IT.
* NVIC and EXTI must be reconfigured properly before triggering the event.
*/
if(HAL_PWREx_GetWakeupFlag(PWR_FLAG_WUF1) != 0)
{
if( (LL_SYSCFG_GetEXTISource(LL_SYSCFG_EXTI_LINE0) == LL_SYSCFG_EXTI_PORTA) )
{
if(((READ_BIT(PWR->CR4, PWR_CR4_WP1) >> PWR_CR4_WP1_Pos) == 0) &&
(LL_EXTI_IsEnabledRisingTrig_0_31(LL_EXTI_LINE_0) == 1) )
{
LL_EXTI_GenerateSWI_0_31(LL_EXTI_LINE_0);
}
if(((READ_BIT(PWR->CR4, PWR_CR4_WP1) >> PWR_CR4_WP1_Pos) == 1) &&
(LL_EXTI_IsEnabledFallingTrig_0_31(LL_EXTI_LINE_0) == 1) )
{
LL_EXTI_GenerateSWI_0_31(LL_EXTI_LINE_0);
}
}
HAL_PWREx_ClearWakeupFlag(PWR_FLAG_WUF1);
}
if(HAL_PWREx_GetWakeupFlag(PWR_FLAG_WUF4) != 0)
{
if( (LL_SYSCFG_GetEXTISource(LL_SYSCFG_EXTI_LINE2) == LL_SYSCFG_EXTI_PORTA) )
{
if(((READ_BIT(PWR->CR4, PWR_CR4_WP4) >> PWR_CR4_WP4_Pos) == 0) &&
(LL_EXTI_IsEnabledRisingTrig_0_31(LL_EXTI_LINE_2) == 1) )
{
LL_EXTI_GenerateSWI_0_31(LL_EXTI_LINE_2);
}
if(((READ_BIT(PWR->CR4, PWR_CR4_WP4) >> PWR_CR4_WP4_Pos) == 1) &&
(LL_EXTI_IsEnabledFallingTrig_0_31(LL_EXTI_LINE_2) == 1) )
{
LL_EXTI_GenerateSWI_0_31(LL_EXTI_LINE_2);
}
}
HAL_PWREx_ClearWakeupFlag(PWR_FLAG_WUF4);
}
return;
}
@@ -1,425 +0,0 @@
/* USER CODE BEGIN Header */
/**
***************************************************************************************
* @file stm32_lpm_if.c
* @author MCD Application Team
* @brief Low layer function to enter/exit low power modes (stop, sleep).
***************************************************************************************
* @attention
*
* Copyright (c) 2026 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 "stm32_lpm_if.h"
#include "stm32_lpm.h"
#include "app_conf.h"
#include "main.h"
#include "standby.h"
/* USER CODE BEGIN include */
/* USER CODE END include */
/* Exported variables --------------------------------------------------------*/
const struct UTIL_LPM_Driver_s UTIL_PowerDriver =
{
PWR_EnterSleepMode,
PWR_ExitSleepMode,
PWR_EnterStopMode,
PWR_ExitStopMode,
PWR_EnterOffMode,
PWR_ExitOffMode,
};
extern RTC_HandleTypeDef hrtc;
void CPUcontextSave(void); /* this function is implemented in startup assembly file */
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
/* Private function prototypes -----------------------------------------------*/
static void Switch_On_HSI(void);
static void EnterLowPower(void);
static void ExitLowPower(void);
#if (CFG_LPM_STANDBY_SUPPORTED != 0)
static void ExitLowPower_standby(void);
#endif
/* USER CODE BEGIN Private_Function_Prototypes */
/* USER CODE END Private_Function_Prototypes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN Private_Typedef */
/* USER CODE END Private_Typedef */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Private_Define */
/* USER CODE END Private_Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Private_Macro */
/* USER CODE END Private_Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Private_Variables */
/* USER CODE END Private_Variables */
/* Functions Definition ------------------------------------------------------*/
/**
* @brief Enters Low Power Off Mode
* @param none
* @retval none
*/
void PWR_EnterOffMode(void)
{
/* USER CODE BEGIN PWR_EnterOffMode_1 */
/* USER CODE END PWR_EnterOffMode_1 */
/**
* The systick should be disabled for the same reason than when the device enters stop mode because
* at this time, the device may enter either OffMode or StopMode.
*/
HAL_SuspendTick();
__HAL_RCC_CLEAR_RESET_FLAGS();
EnterLowPower();
/************************************************************************************
* ENTER OFF MODE
***********************************************************************************/
/*
* There is no risk to clear all the WUF here because in the current implementation, this API is called
* in critical section. If an interrupt occurs while in that critical section before that point,
* the flag is set and will be cleared here but the system will not enter Off Mode
* because an interrupt is pending in the NVIC. The ISR will be executed when moving out
* of this critical section
*/
LL_PWR_ClearFlag_WU();
LL_PWR_SetPowerMode(LL_PWR_MODE_STANDBY);
LL_LPM_EnableDeepSleep(); /**< Set SLEEPDEEP bit of Cortex System Control Register */
/**
* This option is used to ensure that store operations are completed
*/
#if defined (__CC_ARM) || defined (__ARMCC_VERSION)
__force_stores();
#endif
#if (CFG_LPM_STANDBY_SUPPORTED != 0)
LL_EXTI_EnableRisingTrig_32_63(LL_EXTI_LINE_40);
LL_EXTI_EnableEvent_32_63(LL_EXTI_LINE_40);
STBY_AppHwSave();
STBY_SysHwSave();
CPUcontextSave();/* this function will call WFI instruction */
#endif
/* USER CODE BEGIN PWR_EnterOffMode_2 */
/* USER CODE END PWR_EnterOffMode_2 */
return;
}
/**
* @brief Exits Low Power Off Mode
* @param none
* @retval none
*/
void PWR_ExitOffMode(void)
{
/* USER CODE BEGIN PWR_ExitOffMode_1 */
/* USER CODE END PWR_ExitOffMode_1 */
#if (CFG_LPM_STANDBY_SUPPORTED != 0)
if(STBY_BootStatus != 0)
{
STBY_SysHwRestore();
ExitLowPower_standby();
STBY_AppHwRestore();
}
else
{
ExitLowPower();
}
#endif
/* USER CODE BEGIN PWR_ExitOffMode_2 */
/* USER CODE END PWR_ExitOffMode_2 */
return;
}
/**
* @brief Enters Low Power Stop Mode
* @note ARM exists the function when waking up
* @param none
* @retval none
*/
void PWR_EnterStopMode(void)
{
/* USER CODE BEGIN PWR_EnterStopMode_1 */
/* USER CODE END PWR_EnterStopMode_1 */
/**
* When HAL_DBGMCU_EnableDBGStopMode() is called to keep the debugger active in Stop Mode,
* the systick shall be disabled otherwise the cpu may crash when moving out from stop mode
*
* When in production, the HAL_DBGMCU_EnableDBGStopMode() is not called so that the device can reach best power consumption
* However, the systick should be disabled anyway to avoid the case when it is about to expire at the same time the device enters
* stop mode (this will abort the Stop Mode entry).
*/
HAL_SuspendTick();
/**
* This function is called from CRITICAL SECTION
*/
EnterLowPower();
/************************************************************************************
* ENTER STOP MODE
***********************************************************************************/
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1);
LL_LPM_EnableDeepSleep(); /**< Set SLEEPDEEP bit of Cortex System Control Register */
/**
* This option is used to ensure that store operations are completed
*/
#if defined (__CC_ARM) || defined (__ARMCC_VERSION)
__force_stores();
#endif
__WFI();
/* USER CODE BEGIN PWR_EnterStopMode_2 */
/* USER CODE END PWR_EnterStopMode_2 */
return;
}
/**
* @brief Exits Low Power Stop Mode
* @note Enable the pll at 32MHz
* @param none
* @retval none
*/
void PWR_ExitStopMode(void)
{
/* USER CODE BEGIN PWR_ExitStopMode_1 */
/* USER CODE END PWR_ExitStopMode_1 */
/**
* This function is called from CRITICAL SECTION
*/
ExitLowPower();
HAL_ResumeTick();
/* USER CODE BEGIN PWR_ExitStopMode_2 */
/* USER CODE END PWR_ExitStopMode_2 */
return;
}
/**
* @brief Enters Low Power Sleep Mode
* @note ARM exits the function when waking up
* @param none
* @retval none
*/
void PWR_EnterSleepMode(void)
{
/* USER CODE BEGIN PWR_EnterSleepMode_1 */
/* USER CODE END PWR_EnterSleepMode_1 */
HAL_SuspendTick();
/************************************************************************************
* ENTER SLEEP MODE
***********************************************************************************/
LL_LPM_EnableSleep(); /**< Clear SLEEPDEEP bit of Cortex System Control Register */
/**
* This option is used to ensure that store operations are completed
*/
#if defined (__CC_ARM) || defined (__ARMCC_VERSION)
__force_stores();
#endif
__WFI();
/* USER CODE BEGIN PWR_EnterSleepMode_2 */
/* USER CODE END PWR_EnterSleepMode_2 */
return;
}
/**
* @brief Exits Low Power Sleep Mode
* @note ARM exits the function when waking up
* @param none
* @retval none
*/
void PWR_ExitSleepMode(void)
{
/* USER CODE BEGIN PWR_ExitSleepMode_1 */
/* USER CODE END PWR_ExitSleepMode_1 */
HAL_ResumeTick();
/* USER CODE BEGIN PWR_ExitSleepMode_2 */
/* USER CODE END PWR_ExitSleepMode_2 */
return;
}
/**
* @brief Weak CPUcontextSave function definition to implement in startup file.
* @param none
* @retval none
*/
__WEAK void CPUcontextSave(void)
{
#if (CFG_LPM_STANDBY_SUPPORTED != 0)
/*
* If you are here, you have to update your startup_stm32wb15xx_cm4.s file to
* implement CPUcontextSave function like done in latest STM32CubeWB package
* into STM32WB15 BLE applications.
*/
Error_Handler();
#endif
return;
}
/*************************************************************
*
* LOCAL FUNCTIONS
*
*************************************************************/
/**
* @brief Setup the system to enter either stop or off mode
* @param none
* @retval none
*/
static void EnterLowPower(void)
{
/**
* This function is called from CRITICAL SECTION
*/
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));
if (! LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID))
{
if(LL_PWR_IsActiveFlag_C2DS() || LL_PWR_IsActiveFlag_C2SB())
{
/* Release ENTRY_STOP_MODE semaphore */
LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
Switch_On_HSI();
__HAL_FLASH_SET_LATENCY(FLASH_LATENCY_0);
}
}
else
{
Switch_On_HSI();
__HAL_FLASH_SET_LATENCY(FLASH_LATENCY_0);
}
/* Release RCC semaphore */
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
return;
}
/**
* @brief Restore the system to exit stop mode
* @param none
* @retval none
*/
static void ExitLowPower(void)
{
/* Release ENTRY_STOP_MODE semaphore */
LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));
if(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
{
/* Restore the clock configuration of the application in this user section */
/* USER CODE BEGIN ExitLowPower_1 */
/* USER CODE END ExitLowPower_1 */
}
else
{
/* If the application is not running on HSE restore the clock configuration in this user section */
/* USER CODE BEGIN ExitLowPower_2 */
/* USER CODE END ExitLowPower_2 */
}
#if (CFG_LPM_STANDBY_SUPPORTED != 0)
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
#endif
/* Release RCC semaphore */
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
return;
}
#if (CFG_LPM_STANDBY_SUPPORTED != 0)
/**
* @brief Restore the system to exit standby mode
* @param none
* @retval none
*/
static void ExitLowPower_standby(void)
{
/* Release ENTRY_STOP_MODE semaphore */
LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID));
/* USER CODE BEGIN ExitLowPower_standby */
/* USER CODE END ExitLowPower_standby */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
/* Release RCC semaphore */
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
return;
}
#endif
/**
* @brief Switch the system clock on HSI
* @param none
* @retval none
*/
static void Switch_On_HSI(void)
{
LL_RCC_HSI_Enable();
while(!LL_RCC_HSI_IsReady());
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSI);
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI);
return;
}
/* USER CODE BEGIN Private_Functions */
/* USER CODE END Private_Functions */
@@ -1,91 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32wbxx_hal_msp.c
* @brief This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_HSEM_CLK_ENABLE();
/* System interrupt init*/
/* Peripheral interrupt init */
/* RCC_IRQn interrupt configuration */
HAL_NVIC_SetPriority(RCC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(RCC_IRQn);
/* PWR_SOTF_BLEACT_RFPHASE_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PWR_SOTF_BLEACT_RFPHASE_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(PWR_SOTF_BLEACT_RFPHASE_IRQn);
/* HSEM_IRQn interrupt configuration */
HAL_NVIC_SetPriority(HSEM_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(HSEM_IRQn);
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
@@ -1,331 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32wbxx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "main.h"
#include "stm32wbxx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern IPCC_HandleTypeDef hipcc;
extern TIM_HandleTypeDef htim2;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern UART_HandleTypeDef huart1;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* @brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32WBxx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32wbxx.s). */
/******************************************************************************/
/**
* @brief This function handles RCC global interrupt.
*/
void RCC_IRQHandler(void)
{
/* USER CODE BEGIN RCC_IRQn 0 */
/* USER CODE END RCC_IRQn 0 */
/* USER CODE BEGIN RCC_IRQn 1 */
/* USER CODE END RCC_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel1 global interrupt.
*/
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_rx);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel2 global interrupt.
*/
void DMA1_Channel2_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
/* USER CODE END DMA1_Channel2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_tx);
/* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
/* USER CODE END DMA1_Channel2_IRQn 1 */
}
/**
* @brief This function handles TIM2 global interrupt.
*/
void TIM2_IRQHandler(void)
{
/* USER CODE BEGIN TIM2_IRQn 0 */
/* USER CODE END TIM2_IRQn 0 */
HAL_TIM_IRQHandler(&htim2);
/* USER CODE BEGIN TIM2_IRQn 1 */
/* USER CODE END TIM2_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles PWR switching on the fly interrupt, PWR end of BLE activity interrupt, PWR end of critical radio phase interrupt.
*/
void PWR_SOTF_BLEACT_RFPHASE_IRQHandler(void)
{
/* USER CODE BEGIN PWR_SOTF_BLEACT_RFPHASE_IRQn 0 */
/* USER CODE END PWR_SOTF_BLEACT_RFPHASE_IRQn 0 */
/* USER CODE BEGIN PWR_SOTF_BLEACT_RFPHASE_IRQn 1 */
/* USER CODE END PWR_SOTF_BLEACT_RFPHASE_IRQn 1 */
}
/**
* @brief This function handles IPCC RX occupied interrupt.
*/
void IPCC_C1_RX_IRQHandler(void)
{
/* USER CODE BEGIN IPCC_C1_RX_IRQn 0 */
/* USER CODE END IPCC_C1_RX_IRQn 0 */
HAL_IPCC_RX_IRQHandler(&hipcc);
/* USER CODE BEGIN IPCC_C1_RX_IRQn 1 */
/* USER CODE END IPCC_C1_RX_IRQn 1 */
}
/**
* @brief This function handles IPCC TX free interrupt.
*/
void IPCC_C1_TX_IRQHandler(void)
{
/* USER CODE BEGIN IPCC_C1_TX_IRQn 0 */
/* USER CODE END IPCC_C1_TX_IRQn 0 */
HAL_IPCC_TX_IRQHandler(&hipcc);
/* USER CODE BEGIN IPCC_C1_TX_IRQn 1 */
/* USER CODE END IPCC_C1_TX_IRQn 1 */
}
/**
* @brief This function handles HSEM global interrupt.
*/
void HSEM_IRQHandler(void)
{
/* USER CODE BEGIN HSEM_IRQn 0 */
/* USER CODE END HSEM_IRQn 0 */
HAL_HSEM_IRQHandler();
/* USER CODE BEGIN HSEM_IRQn 1 */
/* USER CODE END HSEM_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
@@ -1,244 +0,0 @@
/**
******************************************************************************
* @file syscalls.c
* @author Auto-generated by STM32CubeMX
* @brief Minimal System calls file
*
* For more information about which c-functions
* need which of these lowlevel functions
* please consult the Newlib or Picolibc libc-manual
******************************************************************************
* @attention
*
* Copyright (c) 2020-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.
*
******************************************************************************
*/
/* Includes */
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
/* Variables */
extern int __io_putchar(int ch) __attribute__((weak));
extern int __io_getchar(void) __attribute__((weak));
char *__env[1] = { 0 };
char **environ = __env;
/* Functions */
void initialise_monitor_handles()
{
}
int _getpid(void)
{
return 1;
}
int _kill(int pid, int sig)
{
(void)pid;
(void)sig;
errno = EINVAL;
return -1;
}
void _exit (int status)
{
_kill(status, -1);
while (1) {} /* Make sure we hang here */
}
__attribute__((weak)) int _read(int file, char *ptr, int len)
{
(void)file;
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
*ptr++ = __io_getchar();
}
return len;
}
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
(void)file;
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
__io_putchar(*ptr++);
}
return len;
}
int _close(int file)
{
(void)file;
return -1;
}
int _fstat(int file, struct stat *st)
{
(void)file;
st->st_mode = S_IFCHR;
return 0;
}
int _isatty(int file)
{
(void)file;
return 1;
}
int _lseek(int file, int ptr, int dir)
{
(void)file;
(void)ptr;
(void)dir;
return 0;
}
int _open(char *path, int flags, ...)
{
(void)path;
(void)flags;
/* Pretend like we always fail */
return -1;
}
int _wait(int *status)
{
(void)status;
errno = ECHILD;
return -1;
}
int _unlink(char *name)
{
(void)name;
errno = ENOENT;
return -1;
}
clock_t _times(struct tms *buf)
{
(void)buf;
return -1;
}
int _stat(const char *file, struct stat *st)
{
(void)file;
st->st_mode = S_IFCHR;
return 0;
}
int _link(char *old, char *new)
{
(void)old;
(void)new;
errno = EMLINK;
return -1;
}
int _fork(void)
{
errno = EAGAIN;
return -1;
}
int _execve(char *name, char **argv, char **env)
{
(void)name;
(void)argv;
(void)env;
errno = ENOMEM;
return -1;
}
// --- Picolibc Specific Section ---
#if defined(__PICOLIBC__)
/**
* @brief Picolibc helper function to output a character to a FILE stream.
* This redirects the output to the low-level __io_putchar function.
* @param c Character to write.
* @param file FILE stream pointer (ignored).
* @retval int The character written.
*/
static int starm_putc(char c, FILE *file)
{
(void) file;
__io_putchar(c);
return c;
}
/**
* @brief Picolibc helper function to input a character from a FILE stream.
* This redirects the input from the low-level __io_getchar function.
* @param file FILE stream pointer (ignored).
* @retval int The character read, cast to an unsigned char then int.
*/
static int starm_getc(FILE *file)
{
unsigned char c;
(void) file;
c = __io_getchar();
return c;
}
// Define and initialize the standard I/O streams for Picolibc.
// FDEV_SETUP_STREAM connects the starm_putc and starm_getc helper functions to a FILE structure.
// _FDEV_SETUP_RW indicates the stream is for reading and writing.
static FILE __stdio = FDEV_SETUP_STREAM(starm_putc,
starm_getc,
NULL,
_FDEV_SETUP_RW);
// Assign the standard stream pointers (stdin, stdout, stderr) to the initialized stream.
// Picolibc uses these pointers for standard I/O operations (printf, scanf, etc.).
FILE *const stdin = &__stdio;
__strong_reference(stdin, stdout);
__strong_reference(stdin, stderr);
// Create strong aliases mapping standard C library function names (without underscore)
// to the implemented system call stubs (with underscore). Picolibc uses these
// standard names internally, so this linking is required.
__strong_reference(_read, read);
__strong_reference(_write, write);
__strong_reference(_times, times);
__strong_reference(_execve, execve);
__strong_reference(_fork, fork);
__strong_reference(_link, link);
__strong_reference(_unlink, unlink);
__strong_reference(_stat, stat);
__strong_reference(_wait, wait);
__strong_reference(_open, open);
__strong_reference(_close, close);
__strong_reference(_lseek, lseek);
__strong_reference(_isatty, isatty);
__strong_reference(_fstat, fstat);
__strong_reference(_exit, exit);
__strong_reference(_kill, kill);
__strong_reference(_getpid, getpid);
#endif //__PICOLIBC__
@@ -1,87 +0,0 @@
/**
******************************************************************************
* @file sysmem.c
* @author Generated by STM32CubeMX
* @brief System Memory calls file
*
* For more information about which C functions
* need which of these lowlevel functions
* please consult the Newlib or Picolibc libc manual
******************************************************************************
* @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.
*
******************************************************************************
*/
/* Includes */
#include <errno.h>
#include <stdint.h>
#include <stddef.h>
/**
* Pointer to the current high watermark of the heap usage
*/
static uint8_t *__sbrk_heap_end = NULL;
/**
* @brief _sbrk() allocates memory to the newlib heap and is used by malloc
* and others from the C library
*
* @verbatim
* ############################################################################
* # .data # .bss # newlib heap # MSP stack #
* # # # # Reserved by _Min_Stack_Size #
* ############################################################################
* ^-- RAM start ^-- _end _estack, RAM end --^
* @endverbatim
*
* This implementation starts allocating at the '_end' linker symbol
* The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
* The implementation considers '_estack' linker symbol to be RAM end
* NOTE: If the MSP stack, at any point during execution, grows larger than the
* reserved size, please increase the '_Min_Stack_Size'.
*
* @param incr Memory size
* @return Pointer to allocated memory
*/
void *_sbrk(ptrdiff_t incr)
{
extern uint8_t _end; /* Symbol defined in the linker script */
extern uint8_t _estack; /* Symbol defined in the linker script */
extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
const uint8_t *max_heap = (uint8_t *)stack_limit;
uint8_t *prev_heap_end;
/* Initialize heap end at first call */
if (NULL == __sbrk_heap_end)
{
__sbrk_heap_end = &_end;
}
/* Protect heap from growing into the reserved MSP stack */
if (__sbrk_heap_end + incr > max_heap)
{
errno = ENOMEM;
return (void *)-1;
}
prev_heap_end = __sbrk_heap_end;
__sbrk_heap_end += incr;
return (void *)prev_heap_end;
}
#if defined(__PICOLIBC__)
// Picolibc expects syscalls without the leading underscore.
// This creates a strong alias so that
// calls to `sbrk()` are resolved to our `_sbrk()` implementation.
__strong_reference(_sbrk, sbrk);
#endif
@@ -1,378 +0,0 @@
/**
******************************************************************************
* @file system_stm32wbxx.c
* @author MCD Application Team
* @brief CMSIS Cortex Device Peripheral Access Layer System Source File
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32wbxx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* After each device reset the MSI (4 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to
* configure the system clock before to branch to main program.
*
* This file configures the system clock as follows:
*=============================================================================
*-----------------------------------------------------------------------------
* System Clock source | MSI
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 1
*-----------------------------------------------------------------------------
* APB2 Prescaler | 1
*-----------------------------------------------------------------------------
* PLL_M | 1
*-----------------------------------------------------------------------------
* PLL_N | 8
*-----------------------------------------------------------------------------
* PLL_P | 7
*-----------------------------------------------------------------------------
* PLL_Q | 2
*-----------------------------------------------------------------------------
* PLL_R | 2
*-----------------------------------------------------------------------------
* PLLSAI1_P | NA
*-----------------------------------------------------------------------------
* PLLSAI1_Q | NA
*-----------------------------------------------------------------------------
* PLLSAI1_R | NA
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Disabled
* SDIO and RNG clock |
*-----------------------------------------------------------------------------
*=============================================================================
******************************************************************************
* @attention
*
* Copyright (c) 2019-2021 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.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32WBxx_system
* @{
*/
/** @addtogroup stm32WBxx_System_Private_Includes
* @{
*/
#include "stm32wbxx.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE (32000000UL) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (MSI_VALUE)
#define MSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
#if !defined (LSI_VALUE)
#define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/
#endif /* LSI_VALUE */
#if !defined (LSE_VALUE)
#if defined(STM32WB5Mxx)
#define LSE_VALUE 32774U /*!< Value of the LSE oscillator in Hz */
#else
#define LSE_VALUE 32768U /*!< Value of the LSE oscillator in Hz */
#endif /* STM32WB5Mxx */
#endif /* LSE_VALUE */
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Defines
* @{
*/
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate CPU1 CM4 and/or CPU2
CM0+ vector table anywhere in Sram or Flash. Else vector table will be kept
at address 0x00 which correspond to automatic remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment this line for user vector table remap in Sram else user remap
will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM1_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#if !defined(VECT_TAB_OFFSET)
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_OFFSET */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#if !defined(VECT_TAB_OFFSET)
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_OFFSET */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Variables
* @{
*/
/* The SystemCoreClock variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 4000000UL ; /*CPU1: M4 on MSI clock after startup (4MHz)*/
const uint32_t AHBPrescTable[16UL] = {1UL, 3UL, 5UL, 1UL, 1UL, 6UL, 10UL, 32UL, 2UL, 4UL, 8UL, 16UL, 64UL, 128UL, 256UL, 512UL};
const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL};
const uint32_t MSIRangeTable[16UL] = {100000UL, 200000UL, 400000UL, 800000UL, 1000000UL, 2000000UL, \
4000000UL, 8000000UL, 16000000UL, 24000000UL, 32000000UL, 48000000UL, 0UL, 0UL, 0UL, 0UL
}; /* 0UL values are incorrect cases */
#if defined(STM32WB55xx) || defined(STM32WB5Mxx) || defined(STM32WB35xx) || defined (STM32WB15xx) || defined (STM32WB1Mxx)
const uint32_t SmpsPrescalerTable[4UL][6UL] = {{1UL, 3UL, 2UL, 2UL, 1UL, 2UL}, \
{2UL, 6UL, 4UL, 3UL, 2UL, 4UL}, \
{4UL, 12UL, 8UL, 6UL, 4UL, 8UL}, \
{4UL, 12UL, 8UL, 6UL, 4UL, 8UL}
};
#endif /* STM32WB55xx || STM32WB5Mxx || STM32WB35xx || STM32WB15xx || STM32WB1Mxx */
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system.
* @param None
* @retval None
*/
void SystemInit(void)
{
#if defined(USER_VECT_TAB_ADDRESS)
/* Configure the Vector Table location add offset address ------------------*/
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
#endif /* USER_VECT_TAB_ADDRESS */
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << (10UL * 2UL)) | (3UL << (11UL * 2UL))); /* set CP10 and CP11 Full Access */
#endif /* FPU */
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set MSION bit */
RCC->CR |= RCC_CR_MSION;
/* Reset CFGR register */
RCC->CFGR = 0x00070000U;
/* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */
RCC->CR &= (uint32_t)0xFAF6FEFBU;
/*!< Reset LSI1 and LSI2 bits */
RCC->CSR &= (uint32_t)0xFFFFFFFAU;
/*!< Reset HSI48ON bit */
RCC->CRRCR &= (uint32_t)0xFFFFFFFEU;
/* Reset PLLCFGR register */
RCC->PLLCFGR = 0x22041000U;
#if defined(STM32WB55xx) || defined(STM32WB5Mxx)
/* Reset PLLSAI1CFGR register */
RCC->PLLSAI1CFGR = 0x22041000U;
#endif /* STM32WB55xx || STM32WB5Mxx */
/* Reset HSEBYP bit */
RCC->CR &= 0xFFFBFFFFU;
/* Disable all interrupts */
RCC->CIER = 0x00000000;
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
* or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value
* 4 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 32 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp, msirange, pllvco, pllr, pllsource, pllm;
/* Get MSI Range frequency--------------------------------------------------*/
/*MSI frequency range in Hz*/
msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos];
/* Get SYSCLK source -------------------------------------------------------*/
switch (RCC->CFGR & RCC_CFGR_SWS)
{
case 0x00: /* MSI used as system clock source */
SystemCoreClock = msirange;
break;
case 0x04: /* HSI used as system clock source */
/* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x08: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x0C: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
SYSCLK = PLL_VCO / PLLR
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL ;
if (pllsource == 0x02UL) /* HSI used as PLL clock source */
{
pllvco = (HSI_VALUE / pllm);
}
else if (pllsource == 0x03UL) /* HSE used as PLL clock source */
{
pllvco = (HSE_VALUE / pllm);
}
else /* MSI used as PLL clock source */
{
pllvco = (msirange / pllm);
}
pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL);
SystemCoreClock = pllvco / pllr;
break;
default:
SystemCoreClock = msirange;
break;
}
/* Compute HCLK clock frequency --------------------------------------------*/
/* Get HCLK1 prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
/* HCLK clock frequency */
SystemCoreClock = SystemCoreClock / tmp;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
-112
View File
@@ -1,112 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file tim.c
* @brief This file provides code for the configuration
* of the TIM instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "tim.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
TIM_HandleTypeDef htim2;
/* TIM2 init function */
void MX_TIM2_Init(void)
{
/* USER CODE BEGIN TIM2_Init 0 */
/* USER CODE END TIM2_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM2_Init 1 */
/* USER CODE END TIM2_Init 1 */
htim2.Instance = TIM2;
htim2.Init.Prescaler = 63999;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 99;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM2_Init 2 */
/* USER CODE END TIM2_Init 2 */
}
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspInit 0 */
/* USER CODE END TIM2_MspInit 0 */
/* TIM2 clock enable */
__HAL_RCC_TIM2_CLK_ENABLE();
/* TIM2 interrupt Init */
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspInit 1 */
/* USER CODE END TIM2_MspInit 1 */
}
}
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
{
if(tim_baseHandle->Instance==TIM2)
{
/* USER CODE BEGIN TIM2_MspDeInit 0 */
/* USER CODE END TIM2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM2_CLK_DISABLE();
/* TIM2 interrupt Deinit */
HAL_NVIC_DisableIRQ(TIM2_IRQn);
/* USER CODE BEGIN TIM2_MspDeInit 1 */
/* USER CODE END TIM2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
@@ -1,197 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.c
* @brief This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 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 "usart.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
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;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 DMA Init */
/* USART1_RX Init */
hdma_usart1_rx.Instance = DMA1_Channel1;
hdma_usart1_rx.Init.Request = DMA_REQUEST_USART1_RX;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_NORMAL;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
/* USART1_TX Init */
hdma_usart1_tx.Instance = DMA1_Channel2;
hdma_usart1_tx.Init.Request = DMA_REQUEST_USART1_TX;
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_10);
/* USART1 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmarx);
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
+36 -16
View File
@@ -65,43 +65,54 @@ void PeriphCommonClock_Config(void);
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t uart_rx_data[1028];
__attribute__((aligned(4))) uint8_t uart_rx_data[1028];
__attribute__((aligned(4))) uint8_t ble_out_data[1028];
uint8_t uart_tx_data[1] = {'R'};
bool ready_for_data = false;
volatile uint32_t xfer_len;
volatile uint32_t xfer_len = sizeof(ble_out_data);
volatile uint32_t last_send = 0;
volatile bool do_notify = false;
void SendNotifyTask(void) {
extern uint16_t SizeArrread;
if (!do_notify) {
return;
}
for (int i = 0; 128 * i < xfer_len; ++i) {
for (int i = 0; i < xfer_len; i += 248) {
if (xfer_len - i >= 248) {
SizeArrread = 248;
} else {
SizeArrread = xfer_len - i;
}
Custom_STM_App_Update_Char(
CUSTOM_STM_ARRREAD,
uart_rx_data + i * 128
ble_out_data + i
);
}
last_send = TIM2->CNT;
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {
HAL_GPIO_TogglePin(GPIOA, LED5_Pin);
UTIL_SEQ_SetTask(1<<CFG_TASK_SEND_NOTIFY, UTIL_SEQ_RFU);
// Process data here or something
if (huart->gState == HAL_UART_STATE_READY) {
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
HAL_UART_RxEventTypeTypeDef event = HAL_UARTEx_GetRxEventType(huart);
if (event == HAL_UART_RXEVENT_IDLE || event == HAL_UART_RXEVENT_TC) {
HAL_GPIO_TogglePin(GPIOA, LED5_Pin);
xfer_len = Size;
memcpy(ble_out_data, uart_rx_data, Size);
UTIL_SEQ_SetTask(1<<CFG_TASK_SEND_NOTIFY, UTIL_SEQ_RFU);
// Process data here or something
if (huart->gState == HAL_UART_STATE_READY) {
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
}
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
}
xfer_len = Size;
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
}
void HAL_UART_TXCpltCallback(UART_HandleTypeDef *huart) {}
// tim2 is 1kHz, callback is 1Hz
// tim2 is 1kHz, period is 1<<32 - 1X, should never get called
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM2) {
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
}
}
/* USER CODE END 0 */
@@ -157,17 +168,26 @@ int main(void)
/* Infinite loop */
/* USER CODE BEGIN WHILE */
HAL_TIM_Base_Start_IT(&htim2);
for (uint32_t i = 0; i < 256; ++i) {
((uint32_t*)ble_out_data)[i] = i;
}
UTIL_SEQ_RegTask(1<<CFG_TASK_SEND_NOTIFY, UTIL_SEQ_RFU, SendNotifyTask);
HAL_GPIO_WritePin(GPIOA, LED4_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, LED5_Pin, GPIO_PIN_RESET);
HAL_Delay(1000); // Give the l452 time to start up
HAL_GPIO_WritePin(GPIOA, LED4_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, LED5_Pin, GPIO_PIN_SET);
__HAL_DMA_DISABLE_IT(huart1.hdmarx, DMA_IT_HT);
__HAL_DMA_DISABLE_IT(huart1.hdmarx, DMA_IT_HT);
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, uart_rx_data, sizeof(uart_rx_data));
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
while (1)
{
if (TIM2->CNT - last_send > 4000) {
if (huart1.gState == HAL_UART_STATE_READY) {
HAL_UART_Transmit_DMA(&huart1, uart_tx_data, sizeof(uart_tx_data));
last_send = TIM2->CNT;
}
}
/* USER CODE END WHILE */
MX_APPE_Process();
+1 -1
View File
@@ -1,5 +1,5 @@
##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [4.9.0-B19] date: [Thu Apr 30 16:40:29 CDT 2026]
# File automatically-generated by tool: [projectgenerator] version: [4.9.0-B19] date: [Sat May 09 11:58:26 CDT 2026]
##########################################################################################################################
# ------------------------------------------------
+2 -2
View File
@@ -66,7 +66,7 @@ uint8_t uart_to_l452_data[1];
/* Private variables ---------------------------------------------------------*/
uint16_t SizeArrwrite = 1;
uint16_t SizeArrread = 128;
uint16_t SizeArrread = 248;
/**
* START of Section BLE_DRIVER_CONTEXT
@@ -363,7 +363,7 @@ void SVCCTL_InitCustomSvc(void)
ATTR_PERMISSION_NONE,
GATT_DONT_NOTIFY_EVENTS,
0x10,
CHAR_VALUE_LEN_CONSTANT,
CHAR_VALUE_LEN_VARIABLE,
&(CustomContext.CustomArrreadHdle));
if (ret != BLE_STATUS_SUCCESS)
{
+6 -3
View File
@@ -201,7 +201,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_IPCC_Init-IPCC-false-HAL-true,5-MX_RTC_Init-RTC-false-HAL-true,6-MX_USART1_UART_Init-USART1-false-HAL-true,7-MX_TIM2_Init-TIM2-false-HAL-true,0-MX_HSEM_Init-HSEM-false-HAL-true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_IPCC_Init-IPCC-false-HAL-true,5-MX_RTC_Init-RTC-false-HAL-true,6-MX_USART1_UART_Init-USART1-false-HAL-true,7-MX_TIM2_Init-TIM2-false-HAL-true,8-APPE_Init-STM32_WPAN-false-HAL-false,9-MX_RF_Init-RF-false-HAL-true,0-MX_HSEM_Init-HSEM-false-HAL-true
RCC.AHB2CLKDivider=RCC_SYSCLK_DIV2
RCC.AHBFreq_Value=64000000
RCC.APB1Freq_Value=64000000
@@ -247,6 +247,8 @@ RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.USART1Freq_Value=64000000
RCC.VCOInputFreq_Value=16000000
RCC.VCOOutputFreq_Value=128000000
STM32_WPAN.CFG_BLE_ATT_VALUE_ARRAY_SIZE=1290
STM32_WPAN.CFG_BLE_MAX_ATT_MTU=512
STM32_WPAN.CFG_DEBUGGER_SUPPORTED=0
STM32_WPAN.CFG_IO_CAPABILITY=\ CFG_IO_CAPABILITY_NO_INPUT_NO_OUTPUT
STM32_WPAN.CFG_MITM_PROTECTION=CFG_MITM_PROTECTION_NOT_REQUIRED
@@ -255,7 +257,7 @@ STM32_WPAN.CUSTOM_P2P_SERVER=Disabled
STM32_WPAN.CUSTOM_TEMPLATE=Enabled
STM32_WPAN.DBG_TRACE_USE_CIRCULAR_QUEUE=0
STM32_WPAN.INCLUDE_AD_TYPE_COMPLETE_LOCAL_NAME=1
STM32_WPAN.IPParameters=CUSTOM_P2P_SERVER,CUSTOM_TEMPLATE,CFG_DEBUGGER_SUPPORTED,CFG_USE_SMPS,DBG_TRACE_USE_CIRCULAR_QUEUE,CFG_IO_CAPABILITY,CFG_MITM_PROTECTION,NUMBER_OF_SERVICES,SERVICE1_LONG_NAME,SERVICE1_SHORT_NAME,SERVICE1_NUMBER_OF_CHARACTERISTICS,SERVICE1_CHAR1_LONG_NAME,SERVICE1_CHAR1_SHORT_NAME,SERVICE1_CHAR1_PROP_WRITE,SERVICE1_CHAR1_GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP,SERVICE1_CHAR1_GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP,SERVICE1_CHAR2_LONG_NAME,SERVICE1_CHAR2_SHORT_NAME,SERVICE1_CHAR2_UUID,SERVICE1_CHAR2_VALUE_LENGTH,SERVICE1_CHAR2_PROP_NOTIFY,SERVICE1_CHAR2_GATT_NOTIFY_ATTRIBUTE_WRITE,SERVICE1_CHAR2_GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP,SERVICE1_CHAR2_GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP,INCLUDE_AD_TYPE_COMPLETE_LOCAL_NAME
STM32_WPAN.IPParameters=CUSTOM_P2P_SERVER,CUSTOM_TEMPLATE,CFG_DEBUGGER_SUPPORTED,CFG_USE_SMPS,DBG_TRACE_USE_CIRCULAR_QUEUE,CFG_IO_CAPABILITY,CFG_MITM_PROTECTION,NUMBER_OF_SERVICES,SERVICE1_LONG_NAME,SERVICE1_SHORT_NAME,SERVICE1_NUMBER_OF_CHARACTERISTICS,SERVICE1_CHAR1_LONG_NAME,SERVICE1_CHAR1_SHORT_NAME,SERVICE1_CHAR1_PROP_WRITE,SERVICE1_CHAR1_GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP,SERVICE1_CHAR1_GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP,SERVICE1_CHAR2_LONG_NAME,SERVICE1_CHAR2_SHORT_NAME,SERVICE1_CHAR2_UUID,SERVICE1_CHAR2_VALUE_LENGTH,SERVICE1_CHAR2_PROP_NOTIFY,SERVICE1_CHAR2_GATT_NOTIFY_ATTRIBUTE_WRITE,SERVICE1_CHAR2_GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP,SERVICE1_CHAR2_GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP,INCLUDE_AD_TYPE_COMPLETE_LOCAL_NAME,SERVICE1_CHAR2_LENGTH_CHARACTERISTIC,CFG_BLE_MAX_ATT_MTU,CFG_BLE_ATT_VALUE_ARRAY_SIZE
STM32_WPAN.NUMBER_OF_SERVICES=1
STM32_WPAN.SERVICE1_CHAR1_GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP=\
STM32_WPAN.SERVICE1_CHAR1_GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP=\
@@ -265,11 +267,12 @@ STM32_WPAN.SERVICE1_CHAR1_SHORT_NAME=arrWrite
STM32_WPAN.SERVICE1_CHAR2_GATT_NOTIFY_ATTRIBUTE_WRITE=\
STM32_WPAN.SERVICE1_CHAR2_GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP=\
STM32_WPAN.SERVICE1_CHAR2_GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP=\
STM32_WPAN.SERVICE1_CHAR2_LENGTH_CHARACTERISTIC=CHAR_VALUE_LEN_VARIABLE
STM32_WPAN.SERVICE1_CHAR2_LONG_NAME=arrRead
STM32_WPAN.SERVICE1_CHAR2_PROP_NOTIFY=CHAR_PROP_NOTIFY
STM32_WPAN.SERVICE1_CHAR2_SHORT_NAME=arrRead
STM32_WPAN.SERVICE1_CHAR2_UUID=00 01
STM32_WPAN.SERVICE1_CHAR2_VALUE_LENGTH=128
STM32_WPAN.SERVICE1_CHAR2_VALUE_LENGTH=248
STM32_WPAN.SERVICE1_LONG_NAME=readwriteArr
STM32_WPAN.SERVICE1_NUMBER_OF_CHARACTERISTICS=2
STM32_WPAN.SERVICE1_SHORT_NAME=readwriteArr