提交工程,小程序源码已完成,单片机待完成
This commit is contained in:
322
Core/Bsp/BSP_WF_24/BSP_WF_24使用说明.md
Normal file
322
Core/Bsp/BSP_WF_24/BSP_WF_24使用说明.md
Normal file
@@ -0,0 +1,322 @@
|
||||
# DX-WF-24 WiFi 模块驱动使用说明
|
||||
|
||||
## 目录
|
||||
1. [概述](#概述)
|
||||
2. [文件结构](#文件结构)
|
||||
3. [API 参考](#api-参考)
|
||||
4. [使用示例](#使用示例)
|
||||
5. [注意事项](#注意事项)
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
本驱动用于 STM32F103 与 DX-WF-24 WiFi 模块的串口通信,基于 HAL 库实现,支持:
|
||||
- **DMA 发送** - 非阻塞式数据发送
|
||||
- **DMA + 空闲中断接收** - 自动帧识别接收
|
||||
- **同步应答检测** - AT 指令交互
|
||||
|
||||
---
|
||||
|
||||
## 文件结构
|
||||
|
||||
```
|
||||
BSP_WF_24/
|
||||
├── dx_wf_24.h # 头文件(配置和声明)
|
||||
└── dx_wf_24.c # 实现文件
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API 参考
|
||||
|
||||
### 1. 初始化函数
|
||||
|
||||
#### `WIFI_RECV_DMA_Init()`
|
||||
```c
|
||||
HAL_StatusTypeDef WIFI_RECV_DMA_Init(void);
|
||||
```
|
||||
- **功能**:初始化 WiFi DMA 接收(空闲中断方式)
|
||||
- **调用时机**:main() 中,在 MX_USART1_UART_Init() 之后调用
|
||||
- **返回值**:HAL_OK 表示成功
|
||||
|
||||
---
|
||||
|
||||
### 2. 数据发送
|
||||
|
||||
#### `WIFI_SEND_DMA()`
|
||||
```c
|
||||
HAL_StatusTypeDef WIFI_SEND_DMA(const char *data);
|
||||
```
|
||||
- **功能**:通过 DMA 发送字符串(非阻塞)
|
||||
- **参数**:`data` - 要发送的字符串
|
||||
- **返回值**:
|
||||
- `HAL_OK` - 发送成功启动
|
||||
- `HAL_BUSY` - 上一次发送未完成
|
||||
- `HAL_ERROR` - 参数错误或发送失败
|
||||
|
||||
---
|
||||
|
||||
### 3. 数据接收
|
||||
|
||||
#### `WIFI_Get_Received_Data()`
|
||||
```c
|
||||
int WIFI_Get_Received_Data(uint8_t *buffer, uint16_t len);
|
||||
```
|
||||
- **功能**:获取接收到的数据
|
||||
- **参数**:
|
||||
- `buffer` - 输出缓冲区
|
||||
- `len` - 缓冲区大小
|
||||
- **返回值**:实际复制的数据长度,0 表示无数据
|
||||
|
||||
---
|
||||
|
||||
### 4. 应答检测(新增)
|
||||
|
||||
#### `WIFI_CheckAck()`
|
||||
```c
|
||||
uint8_t WIFI_CheckAck(const char *cmd, const char *expect, uint32_t timeout_ms);
|
||||
```
|
||||
- **功能**:发送 AT 指令并检测应答
|
||||
- **参数**:
|
||||
- `cmd` - 要发送的 AT 指令(如 "AT\r\n")
|
||||
- `expect` - 期望的应答字符串(如 "OK")
|
||||
- `timeout_ms` - 超时时间(毫秒)
|
||||
- **返回值**:
|
||||
- `1` - 收到期望应答
|
||||
- `0` - 超时或收到 ERROR
|
||||
|
||||
### 5. MQTT连接(支持认证)
|
||||
|
||||
#### `WIFI_Connect_MQTT()`
|
||||
```c
|
||||
uint8_t WIFI_Connect_MQTT(const char *wifi_ssid, const char *wifi_pass,
|
||||
const char *mqtt_broker, uint16_t mqtt_port,
|
||||
const char *client_id, const char *mqtt_user,
|
||||
const char *mqtt_pass, const char *sub_topic);
|
||||
```
|
||||
- **功能**:完整MQTT连接流程(WiFi+MQTT)
|
||||
- **参数**:
|
||||
- `wifi_ssid` - WiFi名称
|
||||
- `wifi_pass` - WiFi密码
|
||||
- `mqtt_broker` - MQTT服务器地址
|
||||
- `mqtt_port` - MQTT端口(通常为1883)
|
||||
- `client_id` - MQTT客户端ID(需唯一)
|
||||
- `mqtt_user` - MQTT用户名(传NULL表示无需认证)
|
||||
- `mqtt_pass` - MQTT密码(传NULL表示无需认证)
|
||||
- `sub_topic` - 订阅的主题
|
||||
- **返回值**:
|
||||
- `1` - 连接成功
|
||||
- `0` - 连接失败
|
||||
- **连接步骤**:
|
||||
1. 清理MQTT环境
|
||||
2. AT指令测试
|
||||
3. 设置STA模式
|
||||
4. 连接WiFi(带重试)
|
||||
5. 配置MQTT参数(包括认证信息)
|
||||
6. 连接MQTT服务器(带重试)
|
||||
7. 订阅主题
|
||||
8. 发布上线消息
|
||||
|
||||
---
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 示例1:基础初始化
|
||||
|
||||
```c
|
||||
#include "dx_wf_24.h"
|
||||
|
||||
void System_Init(void)
|
||||
{
|
||||
// HAL 初始化...
|
||||
MX_USART1_UART_Init();
|
||||
|
||||
// 初始化 WiFi DMA 接收
|
||||
if (WIFI_RECV_DMA_Init() != HAL_OK) {
|
||||
elog_e("MAIN", "WiFi init failed!");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 示例2:发送数据
|
||||
|
||||
```c
|
||||
// 发送 AT 指令测试
|
||||
void WiFi_Test(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = WIFI_SEND_DMA("AT\r\n");
|
||||
|
||||
if (status == HAL_OK) {
|
||||
elog_i("WIFI", "Command sent");
|
||||
} else if (status == HAL_BUSY) {
|
||||
elog_w("WIFI", "WiFi busy, try later");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 示例3:检测模块就绪
|
||||
|
||||
```c
|
||||
// 初始化时检测 WiFi 模块
|
||||
uint8_t WiFi_Init_Check(void)
|
||||
{
|
||||
// 发送 AT,期望收到 OK,超时 1 秒
|
||||
if (WIFI_CheckAck("AT\r\n", "OK", 1000)) {
|
||||
elog_i("WIFI", "Module ready");
|
||||
return 1;
|
||||
} else {
|
||||
elog_e("WIFI", "Module not responding");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 示例4:完整的 MQTT 连接(支持认证)
|
||||
|
||||
```c
|
||||
// 连接到 MQTT 服务器(无需认证)
|
||||
void Connect_MQTT_Public(void)
|
||||
{
|
||||
uint8_t success = WIFI_Connect_MQTT(
|
||||
"MyWiFi", // WiFi名称
|
||||
"12345678", // WiFi密码
|
||||
"broker.emqx.io", // MQTT服务器(公共测试服务器)
|
||||
1883, // MQTT端口
|
||||
"PetFeeder-001", // 客户端ID(需唯一)
|
||||
NULL, // MQTT用户名(NULL表示无需认证)
|
||||
NULL, // MQTT密码(NULL表示无需认证)
|
||||
"pet/control" // 订阅主题
|
||||
);
|
||||
|
||||
if (success) {
|
||||
elog_i("MQTT", "Connected to public MQTT server");
|
||||
} else {
|
||||
elog_e("MQTT", "Connection failed");
|
||||
}
|
||||
}
|
||||
|
||||
// 连接到 MQTT 服务器(需要用户名密码认证)
|
||||
void Connect_MQTT_Private(void)
|
||||
{
|
||||
uint8_t success = WIFI_Connect_MQTT(
|
||||
"MyWiFi", // WiFi名称
|
||||
"12345678", // WiFi密码
|
||||
"mqtt.myserver.com", // 私有MQTT服务器
|
||||
1883, // MQTT端口
|
||||
"PetFeeder-001", // 客户端ID
|
||||
"myusername", // MQTT用户名
|
||||
"mypassword", // MQTT密码
|
||||
"pet/control" // 订阅主题
|
||||
);
|
||||
|
||||
if (success) {
|
||||
elog_i("MQTT", "Connected to private MQTT server");
|
||||
} else {
|
||||
elog_e("MQTT", "Connection failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
### 示例5:异步接收处理
|
||||
|
||||
```c
|
||||
// 在任务循环中处理接收数据
|
||||
void WiFi_Task(void)
|
||||
{
|
||||
uint8_t buffer[512];
|
||||
int len;
|
||||
|
||||
while (1) {
|
||||
// 检查是否有新数据
|
||||
len = WIFI_Get_Received_Data(buffer, sizeof(buffer));
|
||||
|
||||
if (len > 0) {
|
||||
// 处理接收到的数据
|
||||
elog_i("WIFI", "Received: %s", buffer);
|
||||
|
||||
// 根据内容做不同处理...
|
||||
if (strstr((char*)buffer, "+IPD")) {
|
||||
// 收到网络数据
|
||||
Process_Network_Data(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
osDelay(10); // 10ms 轮询
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
### 1. 中断配置
|
||||
|
||||
确保 `stm32f1xx_it.c` 中已添加空闲中断处理:
|
||||
|
||||
```c
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
// 检查空闲中断
|
||||
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) {
|
||||
WIFI_UART_IDLE_Callback(&huart1);
|
||||
}
|
||||
|
||||
HAL_UART_IRQHandler(&huart1);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. DMA 配置
|
||||
|
||||
在 `main.c` 的 `MX_USART1_UART_Init()` 中确保启用了 DMA:
|
||||
- USART1_TX: DMA 模式
|
||||
- USART1_RX: DMA 循环模式
|
||||
|
||||
### 3. 缓冲区大小
|
||||
|
||||
默认接收缓冲区为 512 字节,可在 `dx_wf_24.h` 中修改:
|
||||
```c
|
||||
#define WIFI_RX_BUF_SIZE 512
|
||||
```
|
||||
|
||||
### 4. MQTT 用户名密码认证
|
||||
|
||||
- 公共MQTT服务器(如 broker.emqx.io)通常不需要认证,传 `NULL` 即可
|
||||
- 私有MQTT服务器需要用户名和密码,传入对应字符串
|
||||
- 确保 MQTT 服务器已开启用户名密码认证功能
|
||||
|
||||
### 5. 超时处理
|
||||
|
||||
`WIFI_CheckAck()` 是阻塞函数,不适合在中断或高优先级任务中调用。
|
||||
|
||||
### 6. 多线程安全
|
||||
|
||||
当前实现未加互斥锁,如果在多任务环境中同时调用发送/接收,需要额外保护。
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
| 问题 | 可能原因 | 解决方法 |
|
||||
|------|----------|----------|
|
||||
| 收不到数据 | 空闲中断未启用 | 检查 `WIFI_RECV_DMA_Init()` 返回值 |
|
||||
| 数据截断 | 缓冲区太小 | 增大 `WIFI_RX_BUF_SIZE` |
|
||||
| 发送失败 | DMA 忙 | 检查返回值,稍后重试 |
|
||||
| 检测超时 | 波特率不匹配 | 确认模块波特率(默认 115200)|
|
||||
|
||||
---
|
||||
|
||||
## 版本历史
|
||||
|
||||
| 版本 | 日期 | 说明 |
|
||||
|------|------|------|
|
||||
| 1.0 | 2026-02-09 | 初始版本,基础 DMA 收发 |
|
||||
| 1.1 | 2026-02-09 | 新增 `WIFI_CheckAck()` 同步应答检测 |
|
||||
| 1.2 | 2026-02-09 | 新增 `WIFI_Connect_MQTT()` 支持用户名密码认证 |
|
||||
|
||||
---
|
||||
|
||||
## 联系方式
|
||||
|
||||
如有问题,请参考 DX-WF-24 模块 AT 指令手册。
|
||||
370
Core/Bsp/BSP_WF_24/dx_wf_24.c
Normal file
370
Core/Bsp/BSP_WF_24/dx_wf_24.c
Normal file
@@ -0,0 +1,370 @@
|
||||
#include "dx_wf_24.h"
|
||||
#include "elog.h"
|
||||
#include <string.h>
|
||||
#include "cmsis_os.h"
|
||||
#include "stdio.h"
|
||||
/* 发送缓冲区 */
|
||||
#define WIFI_TX_BUF_SIZE 512
|
||||
static uint8_t wifi_tx_buffer[WIFI_TX_BUF_SIZE];
|
||||
static volatile uint8_t wifi_tx_busy = 0;
|
||||
|
||||
/* WiFi 全局结构体 */
|
||||
WIFI_HandleTypeDef wifi = {0};
|
||||
|
||||
/* 日志标签 */
|
||||
#define TAG "WIFI"
|
||||
|
||||
/**
|
||||
* @brief 初始化 WiFi DMA 接收(空闲中断方式)
|
||||
* @retval HAL_StatusTypeDef
|
||||
* @note 在 main 中调用此函数初始化
|
||||
*/
|
||||
HAL_StatusTypeDef WIFI_RECV_DMA_Init(void) {
|
||||
/* 清空缓冲区 */
|
||||
memset(&wifi, 0, sizeof(wifi));
|
||||
|
||||
/* 停止可能正在进行的 DMA */
|
||||
HAL_UART_DMAStop(&huart1);
|
||||
|
||||
/* 启动 DMA 接收(环形缓冲区模式) */
|
||||
HAL_StatusTypeDef status = HAL_UART_Receive_DMA(&huart1, wifi.rx_buffer, WIFI_RX_BUF_SIZE);
|
||||
|
||||
if (status == HAL_OK) {
|
||||
/* 启用空闲中断 - 关键! */
|
||||
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
|
||||
elog_i(TAG, "WiFi DMA RX init OK");
|
||||
} else {
|
||||
elog_e(TAG, "WiFi DMA RX init failed: %d", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 串口空闲中断回调(在 USART1_IRQHandler 中调用)
|
||||
* @param huart 串口句柄
|
||||
* @note 当串口空闲时触发,表示一帧数据接收完成
|
||||
*/
|
||||
void WIFI_UART_IDLE_Callback(UART_HandleTypeDef *huart) {
|
||||
if (huart->Instance != USART1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 清除 IDLE 标志(必须先读 SR 再读 DR) */
|
||||
__HAL_UART_CLEAR_IDLEFLAG(huart);
|
||||
|
||||
/* 停止 DMA 传输,获取已接收数据长度 */
|
||||
HAL_UART_DMAStop(huart);
|
||||
|
||||
/* 计算本次接收的数据长度 */
|
||||
uint16_t recv_len = WIFI_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);
|
||||
|
||||
if (recv_len > 0 && recv_len < WIFI_RX_BUF_SIZE) {
|
||||
wifi.rx_len = recv_len;
|
||||
wifi.rx_buffer[recv_len] = '\0'; // 添加字符串结束符
|
||||
wifi.rx_flag = 1; // 标记接收完成
|
||||
|
||||
elog_d(TAG, "RX[%d]: %s", recv_len, wifi.rx_buffer);
|
||||
}
|
||||
|
||||
/* 重新启动 DMA 接收 */
|
||||
HAL_UART_Receive_DMA(&huart1, wifi.rx_buffer, WIFI_RX_BUF_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取接收到的数据
|
||||
* @param buffer 输出缓冲区
|
||||
* @param len 缓冲区大小
|
||||
* @retval int 实际复制长度,0表示无数据
|
||||
*/
|
||||
int WIFI_Get_Received_Data(uint8_t *buffer, uint16_t len) {
|
||||
if (!wifi.rx_flag || buffer == NULL || len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t copy_len = (wifi.rx_len < len) ? wifi.rx_len : (len - 1);
|
||||
memcpy(buffer, wifi.rx_buffer, copy_len);
|
||||
buffer[copy_len] = '\0';
|
||||
|
||||
wifi.rx_flag = 0; // 清除标志
|
||||
return copy_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 通过 DMA 发送 WiFi 数据(非阻塞)
|
||||
* @param data 要发送的字符串
|
||||
* @retval HAL_StatusTypeDef 发送状态
|
||||
*/
|
||||
HAL_StatusTypeDef WIFI_SEND_DMA(const char *data) {
|
||||
if (data == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
size_t len = strlen(data);
|
||||
if (len == 0) {
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
if (len >= WIFI_TX_BUF_SIZE) {
|
||||
elog_w(TAG, "TX data too long: %d", len);
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if (wifi_tx_busy) {
|
||||
return HAL_BUSY;
|
||||
}
|
||||
|
||||
memcpy(wifi_tx_buffer, data, len);
|
||||
wifi_tx_busy = 1;
|
||||
|
||||
HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(&huart1, wifi_tx_buffer, len);
|
||||
if (status != HAL_OK) {
|
||||
wifi_tx_busy = 0;
|
||||
elog_e(TAG, "TX DMA failed: %d", status);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* DMA 发送完成回调 */
|
||||
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
if (huart->Instance == USART1) {
|
||||
wifi_tx_busy = 0;
|
||||
elog_d(TAG, "TX complete");
|
||||
}
|
||||
}
|
||||
|
||||
/* DMA 接收完成回调(半传输/全传输) */
|
||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
|
||||
if (huart->Instance == USART1) {
|
||||
/* 缓冲区满,标记接收完成 */
|
||||
wifi.rx_len = WIFI_RX_BUF_SIZE;
|
||||
wifi.rx_flag = 1;
|
||||
elog_w(TAG, "RX buffer full!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 检测 WiFi 应答(同步阻塞式)
|
||||
* @param cmd 要发送的 AT 指令
|
||||
* @param expect 期望的应答字符串(如 "OK", "READY")
|
||||
* @param timeout_ms 超时时间(毫秒)
|
||||
* @retval 1-收到期望应答, 0-超时或失败
|
||||
* @note 此函数会阻塞等待应答,建议在初始化阶段使用
|
||||
* @warning 如果在 FreeRTOS 中使用,确保 configUSE_PREEMPTION 已启用
|
||||
*
|
||||
* @example
|
||||
* // 检测模块是否就绪
|
||||
* if (WIFI_CheckAck("AT\r\n", "OK", 1000)) {
|
||||
* elog_i(TAG, "WiFi module ready");
|
||||
* }
|
||||
*/
|
||||
uint8_t WIFI_CheckAck(const char *cmd, const char *expect, uint32_t timeout_ms)
|
||||
{
|
||||
char recv_buf[WIFI_RX_BUF_SIZE];
|
||||
|
||||
if (cmd == NULL || expect == NULL) {
|
||||
elog_e(TAG, "Invalid parameters");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 清空之前的接收标志
|
||||
wifi.rx_flag = 0;
|
||||
|
||||
// 发送指令
|
||||
HAL_StatusTypeDef status = WIFI_SEND_DMA(cmd);
|
||||
if (status != HAL_OK) {
|
||||
elog_e(TAG, "Send failed: %d", status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
elog_d(TAG, "Wait for: %s", expect);
|
||||
|
||||
// 等待应答(轮询方式)
|
||||
uint32_t start_tick = HAL_GetTick();
|
||||
while ((HAL_GetTick() - start_tick) < timeout_ms) {
|
||||
|
||||
// 检查是否接收到数据
|
||||
if (wifi.rx_flag) {
|
||||
// 获取数据并清零标志
|
||||
int len = WIFI_Get_Received_Data((uint8_t *)recv_buf, sizeof(recv_buf));
|
||||
|
||||
if (len > 0) {
|
||||
elog_d(TAG, "Recv: %s", recv_buf);
|
||||
|
||||
// 检查是否包含期望应答
|
||||
if (strstr(recv_buf, expect) != NULL) {
|
||||
elog_i(TAG, "Ack matched: %s", expect);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 检查是否包含错误应答
|
||||
if (strstr(recv_buf, "ERROR") != NULL) {
|
||||
elog_w(TAG, "Got ERROR response");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 小延时,避免忙等
|
||||
HAL_Delay(1);
|
||||
}
|
||||
|
||||
elog_w(TAG, "Ack timeout, expect: %s", expect);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 连接MQTT服务器(完整流程,支持用户名密码认证)
|
||||
* @param wifi_ssid WiFi名称
|
||||
* @param wifi_pass WiFi密码
|
||||
* @param mqtt_broker MQTT服务器地址
|
||||
* @param mqtt_port MQTT端口
|
||||
* @param client_id MQTT客户端ID
|
||||
* @param mqtt_user MQTT用户名(可为NULL表示不需要认证)
|
||||
* @param mqtt_pass MQTT密码(可为NULL表示不需要认证)
|
||||
* @param sub_topic 订阅的主题
|
||||
* @retval 1-连接成功, 0-失败
|
||||
* @note 每一步都有重试机制,失败后不会卡死
|
||||
*
|
||||
* @example
|
||||
* // 连接到MQTT服务器(无需认证)
|
||||
* if (WIFI_Connect_MQTT("MyWiFi", "12345678",
|
||||
* "broker.emqx.io", 1883,
|
||||
* "PetFeeder-001", NULL, NULL, "pet/control")) {
|
||||
* elog_i(TAG, "MQTT connected");
|
||||
* }
|
||||
*
|
||||
* // 连接到MQTT服务器(需要认证)
|
||||
* if (WIFI_Connect_MQTT("MyWiFi", "12345678",
|
||||
* "broker.emqx.io", 1883,
|
||||
* "PetFeeder-001", "user1", "pass123", "pet/control")) {
|
||||
* elog_i(TAG, "MQTT connected");
|
||||
* }
|
||||
*/
|
||||
uint8_t WIFI_Connect_MQTT(const char *wifi_ssid, const char *wifi_pass,
|
||||
const char *mqtt_broker, uint16_t mqtt_port,
|
||||
const char *client_id, const char *mqtt_user,
|
||||
const char *mqtt_pass, const char *sub_topic)
|
||||
{
|
||||
char cmd_buf[128];
|
||||
uint8_t retry_count = 0;
|
||||
const uint8_t max_retry = 3;
|
||||
|
||||
elog_i(TAG, "=== Starting MQTT Connection ===");
|
||||
|
||||
/* 步骤1: 清理环境 */
|
||||
elog_d(TAG, "Step 1: Clean MQTT environment");
|
||||
if (!WIFI_CheckAck("AT+MQTTCLEAN\r\n", "OK", 2000)) {
|
||||
elog_w(TAG, "MQTTCLEAN failed, continue...");
|
||||
}
|
||||
|
||||
/* 步骤2: 恢复出厂设置(可选,根据需要启用) */
|
||||
// elog_d(TAG, "Step 2: Restore factory settings");
|
||||
// if (!WIFI_CheckAck("AT+RESTORE\r\n", "OK", 5000)) {
|
||||
// elog_w(TAG, "RESTORE failed, continue...");
|
||||
// }
|
||||
// osDelay(3000); // 等待模块重启
|
||||
|
||||
/* 步骤3: AT测试 */
|
||||
elog_d(TAG, "Step 3: AT test");
|
||||
retry_count = 0;
|
||||
while (retry_count < max_retry) {
|
||||
if (WIFI_CheckAck("AT\r\n", "OK", 1000)) {
|
||||
break;
|
||||
}
|
||||
retry_count++;
|
||||
elog_w(TAG, "AT test retry %d/%d", retry_count, max_retry);
|
||||
osDelay(500);
|
||||
}
|
||||
if (retry_count >= max_retry) {
|
||||
elog_e(TAG, "AT test failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 步骤4: 设置STA模式 */
|
||||
elog_d(TAG, "Step 4: Set STA mode");
|
||||
if (!WIFI_CheckAck("AT+CWMODE=1\r\n", "OK", 2000)) {
|
||||
elog_e(TAG, "Set STA mode failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 步骤5: 连接WiFi */
|
||||
elog_d(TAG, "Step 5: Connect to WiFi: %s", wifi_ssid);
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "AT+CWJAP=\"%s\",\"%s\"\r\n", wifi_ssid, wifi_pass);
|
||||
|
||||
retry_count = 0;
|
||||
while (retry_count < max_retry) {
|
||||
if (WIFI_CheckAck(cmd_buf, "WIFI GOT IP", 10000)) {
|
||||
elog_i(TAG, "WiFi connected successfully");
|
||||
break;
|
||||
}
|
||||
retry_count++;
|
||||
elog_w(TAG, "WiFi connect retry %d/%d", retry_count, max_retry);
|
||||
osDelay(2000);
|
||||
}
|
||||
if (retry_count >= max_retry) {
|
||||
elog_e(TAG, "WiFi connect failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 步骤6: 配置MQTT用户参数(用户名和密码) */
|
||||
if (mqtt_user != NULL && mqtt_pass != NULL) {
|
||||
elog_d(TAG, "Step 6: Configure MQTT user authentication");
|
||||
// 配置MQTT用户参数:LinkID=0, scheme=1, client_id, username, password
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",
|
||||
client_id, mqtt_user, mqtt_pass);
|
||||
if (!WIFI_CheckAck(cmd_buf, "OK", 3000)) {
|
||||
elog_e(TAG, "MQTT user configuration failed");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
elog_d(TAG, "Step 6: Configure MQTT without authentication");
|
||||
// 无认证模式
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTUSERCFG=0,1,\"%s\",\"\",\"\",0,0,\"\"\r\n", client_id);
|
||||
if (!WIFI_CheckAck(cmd_buf, "OK", 3000)) {
|
||||
elog_e(TAG, "MQTT configuration failed");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* 步骤7: 连接MQTT服务器 */
|
||||
elog_d(TAG, "Step 7: Connect to MQTT broker: %s:%d", mqtt_broker, mqtt_port);
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTCONN=0,\"%s\",%d,0\r\n", mqtt_broker, mqtt_port);
|
||||
|
||||
retry_count = 0;
|
||||
while (retry_count < max_retry) {
|
||||
if (WIFI_CheckAck(cmd_buf, "MQTTCONNECTED:", 5000)) {
|
||||
elog_i(TAG, "MQTT broker connected");
|
||||
break;
|
||||
}
|
||||
retry_count++;
|
||||
elog_w(TAG, "MQTT connect retry %d/%d", retry_count, max_retry);
|
||||
osDelay(1000);
|
||||
}
|
||||
if (retry_count >= max_retry) {
|
||||
elog_e(TAG, "MQTT connect failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 步骤8: 订阅主题 */
|
||||
elog_d(TAG, "Step 8: Subscribe topic: %s", sub_topic);
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTSUB=0,\"%s\",0\r\n", sub_topic);
|
||||
if (!WIFI_CheckAck(cmd_buf, "OK", 3000)) {
|
||||
elog_e(TAG, "Subscribe failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 步骤9: 发布上线消息 */
|
||||
elog_d(TAG, "Step 9: Publish online message");
|
||||
const char *online_topic = "device/online";
|
||||
const char *online_msg = "{\"device\":\"PetFeeder\",\"status\":\"online\"}";
|
||||
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTPUB=0,\"%s\",\"%s\",0,0\r\n", online_topic, online_msg);
|
||||
if (!WIFI_CheckAck(cmd_buf, "OK", 2000)) {
|
||||
elog_w(TAG, "Publish online message failed, continue...");
|
||||
}
|
||||
|
||||
elog_i(TAG, "=== MQTT Connection Completed Successfully ===");
|
||||
return 1;
|
||||
}
|
||||
37
Core/Bsp/BSP_WF_24/dx_wf_24.h
Normal file
37
Core/Bsp/BSP_WF_24/dx_wf_24.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef __DX_WF_24_H__
|
||||
#define __DX_WF_24_H__
|
||||
|
||||
#include "usart.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* 默认超时时间(毫秒) */
|
||||
#define WIFI_DEFAULT_TIMEOUT 1000
|
||||
|
||||
/* WiFi 接收缓冲区大小 */
|
||||
#define WIFI_RX_BUF_SIZE 512
|
||||
|
||||
/* WiFi 数据结构体 */
|
||||
typedef struct {
|
||||
uint8_t rx_buffer[WIFI_RX_BUF_SIZE]; // 接收缓冲区
|
||||
uint16_t rx_len; // 本次接收长度
|
||||
uint8_t rx_flag; // 接收完成标志
|
||||
} WIFI_HandleTypeDef;
|
||||
|
||||
extern WIFI_HandleTypeDef wifi;
|
||||
|
||||
/* 函数声明 */
|
||||
HAL_StatusTypeDef WIFI_SEND_DMA(const char *data);
|
||||
HAL_StatusTypeDef WIFI_RECV_DMA_Init(void);
|
||||
void WIFI_UART_IDLE_Callback(UART_HandleTypeDef *huart);
|
||||
int WIFI_Get_Received_Data(uint8_t *buffer, uint16_t len);
|
||||
|
||||
/* 同步应答检测函数 */
|
||||
uint8_t WIFI_CheckAck(const char *cmd, const char *expect, uint32_t timeout_ms);
|
||||
|
||||
/* MQTT连接函数 */
|
||||
uint8_t WIFI_Connect_MQTT(const char *wifi_ssid, const char *wifi_pass,
|
||||
const char *mqtt_broker, uint16_t mqtt_port,
|
||||
const char *client_id, const char *mqtt_user,
|
||||
const char *mqtt_pass, const char *sub_topic);
|
||||
|
||||
#endif /* __DX_WF_24_H__ */
|
||||
272
Core/Bsp/easylogger/inc/elog.h
Normal file
272
Core/Bsp/easylogger/inc/elog.h
Normal file
@@ -0,0 +1,272 @@
|
||||
//
|
||||
// Created by wangb on 25-6-4.
|
||||
//
|
||||
|
||||
#ifndef ELOG_H
|
||||
#define ELOG_H
|
||||
|
||||
#include "elog_cfg.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* output log's level */
|
||||
#define ELOG_LVL_ASSERT 0
|
||||
#define ELOG_LVL_ERROR 1
|
||||
#define ELOG_LVL_WARN 2
|
||||
#define ELOG_LVL_INFO 3
|
||||
#define ELOG_LVL_DEBUG 4
|
||||
#define ELOG_LVL_VERBOSE 5
|
||||
|
||||
|
||||
/* the output silent level and all level for filter setting */
|
||||
#define ELOG_FILTER_LVL_SILENT ELOG_LVL_ASSERT
|
||||
#define ELOG_FILTER_LVL_ALL ELOG_LVL_VERBOSE
|
||||
|
||||
/* output log's level total number */
|
||||
#define ELOG_LVL_TOTAL_NUM 6
|
||||
|
||||
/* EasyLogger software version number */
|
||||
#define ELOG_SW_VERSION "2.2.99"
|
||||
|
||||
/* EasyLogger assert for developer. */
|
||||
#ifdef ELOG_ASSERT_ENABLE
|
||||
#define ELOG_ASSERT(EXPR) \
|
||||
if (!(EXPR)) \
|
||||
{ \
|
||||
if (elog_assert_hook == NULL) { \
|
||||
elog_a("elog", "(%s) has assert failed at %s:%ld.", #EXPR, __FUNCTION__, __LINE__); \
|
||||
while (1); \
|
||||
} else { \
|
||||
elog_assert_hook(#EXPR, __FUNCTION__, __LINE__); \
|
||||
} \
|
||||
}
|
||||
#else
|
||||
#define ELOG_ASSERT(EXPR) ((void)0);
|
||||
#endif
|
||||
|
||||
#ifndef ELOG_OUTPUT_ENABLE
|
||||
#define elog_raw(...)
|
||||
#define elog_assert(tag, ...)
|
||||
#define elog_error(tag, ...)
|
||||
#define elog_warn(tag, ...)
|
||||
#define elog_info(tag, ...)
|
||||
#define elog_debug(tag, ...)
|
||||
#define elog_verbose(tag, ...)
|
||||
#else /* ELOG_OUTPUT_ENABLE */
|
||||
|
||||
#ifdef ELOG_FMT_USING_FUNC
|
||||
#define ELOG_OUTPUT_FUNC __FUNCTION__
|
||||
#else
|
||||
#define ELOG_OUTPUT_FUNC NULL
|
||||
#endif
|
||||
|
||||
#ifdef ELOG_FMT_USING_DIR
|
||||
#define ELOG_OUTPUT_DIR __FILE__
|
||||
#else
|
||||
#define ELOG_OUTPUT_DIR NULL
|
||||
#endif
|
||||
|
||||
#ifdef ELOG_FMT_USING_LINE
|
||||
#define ELOG_OUTPUT_LINE __LINE__
|
||||
#else
|
||||
#define ELOG_OUTPUT_LINE 0
|
||||
#endif
|
||||
|
||||
#define elog_raw(...) elog_raw_output(__VA_ARGS__)
|
||||
#if ELOG_OUTPUT_LVL >= ELOG_LVL_ASSERT
|
||||
#define elog_assert(tag, ...) \
|
||||
elog_output(ELOG_LVL_ASSERT, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
|
||||
#else
|
||||
#define elog_assert(tag, ...)
|
||||
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_ASSERT */
|
||||
|
||||
#if ELOG_OUTPUT_LVL >= ELOG_LVL_ERROR
|
||||
#define elog_error(tag, ...) \
|
||||
elog_output(ELOG_LVL_ERROR, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
|
||||
#else
|
||||
#define elog_error(tag, ...)
|
||||
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_ERROR */
|
||||
|
||||
#if ELOG_OUTPUT_LVL >= ELOG_LVL_WARN
|
||||
#define elog_warn(tag, ...) \
|
||||
elog_output(ELOG_LVL_WARN, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
|
||||
#else
|
||||
#define elog_warn(tag, ...)
|
||||
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_WARN */
|
||||
|
||||
#if ELOG_OUTPUT_LVL >= ELOG_LVL_INFO
|
||||
#define elog_info(tag, ...) \
|
||||
elog_output(ELOG_LVL_INFO, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
|
||||
#else
|
||||
#define elog_info(tag, ...)
|
||||
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_INFO */
|
||||
|
||||
#if ELOG_OUTPUT_LVL >= ELOG_LVL_DEBUG
|
||||
#define elog_debug(tag, ...) \
|
||||
elog_output(ELOG_LVL_DEBUG, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
|
||||
#else
|
||||
#define elog_debug(tag, ...)
|
||||
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_DEBUG */
|
||||
|
||||
#if ELOG_OUTPUT_LVL == ELOG_LVL_VERBOSE
|
||||
#define elog_verbose(tag, ...) \
|
||||
elog_output(ELOG_LVL_VERBOSE, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
|
||||
#else
|
||||
#define elog_verbose(tag, ...)
|
||||
#endif /* ELOG_OUTPUT_LVL == ELOG_LVL_VERBOSE */
|
||||
#endif /* ELOG_OUTPUT_ENABLE */
|
||||
|
||||
/* all formats index */
|
||||
typedef enum {
|
||||
ELOG_FMT_LVL = 1 << 0, /**< level */
|
||||
ELOG_FMT_TAG = 1 << 1, /**< tag */
|
||||
ELOG_FMT_TIME = 1 << 2, /**< current time */
|
||||
ELOG_FMT_P_INFO = 1 << 3, /**< process info */
|
||||
ELOG_FMT_T_INFO = 1 << 4, /**< thread info */
|
||||
ELOG_FMT_DIR = 1 << 5, /**< file directory and name */
|
||||
ELOG_FMT_FUNC = 1 << 6, /**< function name */
|
||||
ELOG_FMT_LINE = 1 << 7, /**< line number */
|
||||
} ElogFmtIndex;
|
||||
|
||||
/* macro definition for all formats */
|
||||
#define ELOG_FMT_ALL (ELOG_FMT_LVL|ELOG_FMT_TAG|ELOG_FMT_TIME|ELOG_FMT_P_INFO|ELOG_FMT_T_INFO| \
|
||||
ELOG_FMT_DIR|ELOG_FMT_FUNC|ELOG_FMT_LINE)
|
||||
|
||||
/* output log's tag filter */
|
||||
typedef struct {
|
||||
uint8_t level;
|
||||
char tag[ELOG_FILTER_TAG_MAX_LEN + 1];
|
||||
bool tag_use_flag; /**< false : tag is no used true: tag is used */
|
||||
} ElogTagLvlFilter, *ElogTagLvlFilter_t;
|
||||
|
||||
/* output log's filter */
|
||||
typedef struct {
|
||||
uint8_t level;
|
||||
char tag[ELOG_FILTER_TAG_MAX_LEN + 1];
|
||||
char keyword[ELOG_FILTER_KW_MAX_LEN + 1];
|
||||
ElogTagLvlFilter tag_lvl[ELOG_FILTER_TAG_LVL_MAX_NUM];
|
||||
} ElogFilter, *ElogFilter_t;
|
||||
|
||||
/* easy logger */
|
||||
typedef struct {
|
||||
ElogFilter filter;
|
||||
size_t enabled_fmt_set[ELOG_LVL_TOTAL_NUM];
|
||||
bool init_ok;
|
||||
bool output_enabled;
|
||||
bool output_lock_enabled;
|
||||
bool output_is_locked_before_enable;
|
||||
bool output_is_locked_before_disable;
|
||||
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
bool text_color_enabled;
|
||||
#endif
|
||||
|
||||
}EasyLogger, *EasyLogger_t;
|
||||
|
||||
/* EasyLogger error code */
|
||||
typedef enum {
|
||||
ELOG_NO_ERR,
|
||||
} ElogErrCode;
|
||||
|
||||
/* elog.c */
|
||||
ElogErrCode elog_init(void);
|
||||
void elog_deinit(void);
|
||||
void elog_start(void);
|
||||
void elog_stop(void);
|
||||
void elog_set_output_enabled(bool enabled);
|
||||
bool elog_get_output_enabled(void);
|
||||
void elog_set_text_color_enabled(bool enabled);
|
||||
bool elog_get_text_color_enabled(void);
|
||||
void elog_set_fmt(uint8_t level, size_t set);
|
||||
void elog_set_filter(uint8_t level, const char *tag, const char *keyword);
|
||||
void elog_set_filter_lvl(uint8_t level);
|
||||
void elog_set_filter_tag(const char *tag);
|
||||
void elog_set_filter_kw(const char *keyword);
|
||||
void elog_set_filter_tag_lvl(const char *tag, uint8_t level);
|
||||
uint8_t elog_get_filter_tag_lvl(const char *tag);
|
||||
void elog_raw_output(const char *format, ...);
|
||||
void elog_output(uint8_t level, const char *tag, const char *file, const char *func,
|
||||
const long line, const char *format, ...);
|
||||
void elog_output_lock_enabled(bool enabled);
|
||||
extern void (*elog_assert_hook)(const char* expr, const char* func, size_t line);
|
||||
void elog_assert_set_hook(void (*hook)(const char* expr, const char* func, size_t line));
|
||||
int8_t elog_find_lvl(const char *log);
|
||||
const char *elog_find_tag(const char *log, uint8_t lvl, size_t *tag_len);
|
||||
void elog_hexdump(const char *name, uint8_t width, const void *buf, uint16_t size);
|
||||
|
||||
#define elog_a(tag, ...) elog_assert(tag, __VA_ARGS__)
|
||||
#define elog_e(tag, ...) elog_error(tag, __VA_ARGS__)
|
||||
#define elog_w(tag, ...) elog_warn(tag, __VA_ARGS__)
|
||||
#define elog_i(tag, ...) elog_info(tag, __VA_ARGS__)
|
||||
#define elog_d(tag, ...) elog_debug(tag, __VA_ARGS__)
|
||||
#define elog_v(tag, ...) elog_verbose(tag, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* log API short definition
|
||||
* NOTE: The `LOG_TAG` and `LOG_LVL` must defined before including the <elog.h> when you want to use log_x API.
|
||||
*/
|
||||
#if !defined(LOG_TAG)
|
||||
#define LOG_TAG "NO_TAG"
|
||||
#endif
|
||||
#if !defined(LOG_LVL)
|
||||
#define LOG_LVL ELOG_LVL_VERBOSE
|
||||
#endif
|
||||
#if LOG_LVL >= ELOG_LVL_ASSERT
|
||||
#define log_a(...) elog_a(LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define log_a(...) ((void)0);
|
||||
#endif
|
||||
#if LOG_LVL >= ELOG_LVL_ERROR
|
||||
#define log_e(...) elog_e(LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define log_e(...) ((void)0);
|
||||
#endif
|
||||
#if LOG_LVL >= ELOG_LVL_WARN
|
||||
#define log_w(...) elog_w(LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define log_w(...) ((void)0);
|
||||
#endif
|
||||
#if LOG_LVL >= ELOG_LVL_INFO
|
||||
#define log_i(...) elog_i(LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define log_i(...) ((void)0);
|
||||
#endif
|
||||
#if LOG_LVL >= ELOG_LVL_DEBUG
|
||||
#define log_d(...) elog_d(LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define log_d(...) ((void)0);
|
||||
#endif
|
||||
#if LOG_LVL >= ELOG_LVL_VERBOSE
|
||||
#define log_v(...) elog_v(LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define log_v(...) ((void)0);
|
||||
#endif
|
||||
|
||||
/* assert API short definition */
|
||||
#if !defined(assert)
|
||||
#define assert ELOG_ASSERT
|
||||
#endif
|
||||
|
||||
/* elog_buf.c */
|
||||
void elog_buf_enabled(bool enabled);
|
||||
void elog_flush(void);
|
||||
|
||||
/* elog_async.c */
|
||||
void elog_async_enabled(bool enabled);
|
||||
size_t elog_async_get_log(char *log, size_t size);
|
||||
size_t elog_async_get_line_log(char *log, size_t size);
|
||||
|
||||
/* elog_utils.c */
|
||||
size_t elog_strcpy(size_t cur_len, char *dst, const char *src);
|
||||
size_t elog_cpyln(char *line, const char *log, size_t len);
|
||||
void *elog_memcpy(void *dst, const void *src, size_t count);
|
||||
void easylogger_init(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //ELOG_H
|
||||
59
Core/Bsp/easylogger/inc/elog_cfg.h
Normal file
59
Core/Bsp/easylogger/inc/elog_cfg.h
Normal file
@@ -0,0 +1,59 @@
|
||||
//
|
||||
// Created by wangb on 25-6-4.
|
||||
//
|
||||
|
||||
#ifndef _ELOG_CFG_H_
|
||||
#define _ELOG_CFG_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* enable log output. */
|
||||
#define ELOG_OUTPUT_ENABLE
|
||||
/* setting static output log level. range: from ELOG_LVL_ASSERT to ELOG_LVL_VERBOSE */
|
||||
#define ELOG_OUTPUT_LVL ELOG_LVL_VERBOSE
|
||||
/* enable assert check */
|
||||
#define ELOG_ASSERT_ENABLE
|
||||
/* buffer size for every line's log */
|
||||
#define ELOG_LINE_BUF_SIZE 1024
|
||||
/* output line number max length */
|
||||
#define ELOG_LINE_NUM_MAX_LEN 5
|
||||
/* output filter's tag max length */
|
||||
#define ELOG_FILTER_TAG_MAX_LEN 30
|
||||
/* output filter's keyword max length */
|
||||
#define ELOG_FILTER_KW_MAX_LEN 16
|
||||
/* output filter's tag level max num */
|
||||
#define ELOG_FILTER_TAG_LVL_MAX_NUM 5
|
||||
/* output newline sign */
|
||||
#define ELOG_NEWLINE_SIGN "\r\n" //换行
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* enable log color */
|
||||
#define ELOG_COLOR_ENABLE
|
||||
/* change the some level logs to not default color if you want */
|
||||
#define ELOG_COLOR_ASSERT (F_MAGENTA B_NULL S_NORMAL)
|
||||
#define ELOG_COLOR_ERROR (F_RED B_NULL S_NORMAL)
|
||||
#define ELOG_COLOR_WARN (F_YELLOW B_NULL S_NORMAL)
|
||||
#define ELOG_COLOR_INFO (F_CYAN B_NULL S_NORMAL)
|
||||
#define ELOG_COLOR_DEBUG (F_GREEN B_NULL S_NORMAL)
|
||||
#define ELOG_COLOR_VERBOSE (F_BLUE B_NULL S_NORMAL)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* enable log fmt */
|
||||
/* comment it if you don't want to output them at all */
|
||||
#define ELOG_FMT_USING_FUNC
|
||||
#define ELOG_FMT_USING_DIR
|
||||
#define ELOG_FMT_USING_LINE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* enable asynchronous output mode */
|
||||
//#define ELOG_ASYNC_OUTPUT_ENABLE
|
||||
/* the highest output level for async mode, other level will sync output */
|
||||
#define ELOG_ASYNC_OUTPUT_LVL ELOG_LVL_ASSERT
|
||||
/* buffer size for asynchronous output mode */
|
||||
#define ELOG_ASYNC_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 10)
|
||||
/* each asynchronous output's log which must end with newline sign */
|
||||
#define ELOG_ASYNC_LINE_OUTPUT
|
||||
/* asynchronous output mode using POSIX pthread implementation */
|
||||
#define ELOG_ASYNC_OUTPUT_USING_PTHREAD
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* enable buffered output mode */
|
||||
//#define ELOG_BUF_OUTPUT_ENABLE
|
||||
/* buffer size for buffered output mode */
|
||||
#define ELOG_BUF_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 10)
|
||||
|
||||
#endif /* _ELOG_CFG_H_ */
|
||||
127
Core/Bsp/easylogger/port/elog_port.c
Normal file
127
Core/Bsp/easylogger/port/elog_port.c
Normal file
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// Created by wangb on 25-6-4.
|
||||
//
|
||||
|
||||
#include "elog.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "main.h"
|
||||
|
||||
/**
|
||||
* EasyLogger port initialize
|
||||
*
|
||||
* @return result
|
||||
*/
|
||||
ElogErrCode elog_port_init(void) {
|
||||
ElogErrCode result = ELOG_NO_ERR;
|
||||
|
||||
/* add your code here */
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* EasyLogger port deinitialize
|
||||
*
|
||||
*/
|
||||
void elog_port_deinit(void) {
|
||||
/* add your code here */
|
||||
}
|
||||
|
||||
/**
|
||||
* output log port interface
|
||||
*
|
||||
* @param log output of log
|
||||
* @param size log size
|
||||
*/
|
||||
void elog_port_output(const char *log, size_t size) {
|
||||
/* add your code here */
|
||||
printf("%.*s", size, log); //elog 的输出
|
||||
}
|
||||
|
||||
/**
|
||||
* output lock
|
||||
*/
|
||||
void elog_port_output_lock(void) {
|
||||
/* add your code here */
|
||||
|
||||
__disable_irq(); //关闭全局中断
|
||||
}
|
||||
|
||||
/**
|
||||
* output unlock
|
||||
*/
|
||||
void elog_port_output_unlock(void) {
|
||||
/* add your code here */
|
||||
__enable_irq(); //开启全局中断
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* get current time interface
|
||||
*
|
||||
* @return current time
|
||||
*/
|
||||
const char *elog_port_get_time(void) {
|
||||
// static char rtc_time[20]; // 静态缓冲区,存 "YYYY-MM-DD HH:MM:SS"
|
||||
// RTC_TimeTypeDef sTime = {0};
|
||||
// RTC_DateTypeDef sDate = {0};
|
||||
//
|
||||
// // 1. 读取RTC时间(先读时间,再读日期,HAL库要求)
|
||||
// HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
|
||||
// HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
|
||||
//
|
||||
// // 2. 格式化时间字符串(直接拼接到静态数组)
|
||||
// snprintf(rtc_time, sizeof(rtc_time), "20%02d-%02d-%02d %02d:%02d:%02d",
|
||||
// sDate.Year, // 25 → 2025
|
||||
// sDate.Month, // 1-12
|
||||
// sDate.Date, // 1-31
|
||||
// sTime.Hours, // 0-23
|
||||
// sTime.Minutes, // 0-59
|
||||
// sTime.Seconds); // 0-59
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get current process name interface
|
||||
*
|
||||
* @return current process name
|
||||
*/
|
||||
const char *elog_port_get_p_info(void) {
|
||||
/* add your code here */
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* get current thread name interface
|
||||
*
|
||||
* @return current thread name
|
||||
*/
|
||||
const char *elog_port_get_t_info(void) {
|
||||
/* add your code here */
|
||||
//获取STM32 的线程接口
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void easylogger_init(void) {
|
||||
/* init Easylogger */
|
||||
elog_init();
|
||||
|
||||
/* set EasyLogger log format */
|
||||
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL & ~ELOG_FMT_P_INFO);
|
||||
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
|
||||
elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
|
||||
elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
|
||||
elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_P_INFO));
|
||||
elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_P_INFO));
|
||||
|
||||
|
||||
/* start EasyLogger */
|
||||
elog_start();
|
||||
}
|
||||
912
Core/Bsp/easylogger/src/elog.c
Normal file
912
Core/Bsp/easylogger/src/elog.c
Normal file
@@ -0,0 +1,912 @@
|
||||
//
|
||||
// Created by wangb on 25-6-4.
|
||||
//
|
||||
|
||||
|
||||
#define LOG_TAG "elog"
|
||||
|
||||
#include "elog.h"
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if !defined(ELOG_OUTPUT_LVL)
|
||||
#error "Please configure static output log level (in elog_cfg.h)"
|
||||
#endif
|
||||
|
||||
#if !defined(ELOG_LINE_NUM_MAX_LEN)
|
||||
#error "Please configure output line number max length (in elog_cfg.h)"
|
||||
#endif
|
||||
|
||||
#if !defined(ELOG_LINE_BUF_SIZE)
|
||||
#error "Please configure buffer size for every line's log (in elog_cfg.h)"
|
||||
#endif
|
||||
|
||||
#if !defined(ELOG_FILTER_TAG_MAX_LEN)
|
||||
#error "Please configure output filter's tag max length (in elog_cfg.h)"
|
||||
#endif
|
||||
|
||||
#if !defined(ELOG_FILTER_KW_MAX_LEN)
|
||||
#error "Please configure output filter's keyword max length (in elog_cfg.h)"
|
||||
#endif
|
||||
|
||||
#if !defined(ELOG_NEWLINE_SIGN)
|
||||
#error "Please configure output newline sign (in elog_cfg.h)"
|
||||
#endif
|
||||
|
||||
/* output filter's tag level max num */
|
||||
#ifndef ELOG_FILTER_TAG_LVL_MAX_NUM
|
||||
#define ELOG_FILTER_TAG_LVL_MAX_NUM 4
|
||||
#endif
|
||||
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
/**
|
||||
* CSI(Control Sequence Introducer/Initiator) sign
|
||||
* more information on https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
*/
|
||||
#define CSI_START "\033["
|
||||
#define CSI_END "\033[0m"
|
||||
/* output log front color */
|
||||
#define F_BLACK "30;"
|
||||
#define F_RED "31;"
|
||||
#define F_GREEN "32;"
|
||||
#define F_YELLOW "33;"
|
||||
#define F_BLUE "34;"
|
||||
#define F_MAGENTA "35;"
|
||||
#define F_CYAN "36;"
|
||||
#define F_WHITE "37;"
|
||||
/* output log background color */
|
||||
#define B_NULL
|
||||
#define B_BLACK "40;"
|
||||
#define B_RED "41;"
|
||||
#define B_GREEN "42;"
|
||||
#define B_YELLOW "43;"
|
||||
#define B_BLUE "44;"
|
||||
#define B_MAGENTA "45;"
|
||||
#define B_CYAN "46;"
|
||||
#define B_WHITE "47;"
|
||||
/* output log fonts style */
|
||||
#define S_BOLD "1m"
|
||||
#define S_UNDERLINE "4m"
|
||||
#define S_BLINK "5m"
|
||||
#define S_NORMAL "22m"
|
||||
/* output log default color definition: [front color] + [background color] + [show style] */
|
||||
#ifndef ELOG_COLOR_ASSERT
|
||||
#define ELOG_COLOR_ASSERT (F_MAGENTA B_NULL S_NORMAL)
|
||||
#endif
|
||||
#ifndef ELOG_COLOR_ERROR
|
||||
#define ELOG_COLOR_ERROR (F_RED B_NULL S_NORMAL)
|
||||
#endif
|
||||
#ifndef ELOG_COLOR_WARN
|
||||
#define ELOG_COLOR_WARN (F_YELLOW B_NULL S_NORMAL)
|
||||
#endif
|
||||
#ifndef ELOG_COLOR_INFO
|
||||
#define ELOG_COLOR_INFO (F_CYAN B_NULL S_NORMAL)
|
||||
#endif
|
||||
#ifndef ELOG_COLOR_DEBUG
|
||||
#define ELOG_COLOR_DEBUG (F_GREEN B_NULL S_NORMAL)
|
||||
#endif
|
||||
#ifndef ELOG_COLOR_VERBOSE
|
||||
#define ELOG_COLOR_VERBOSE (F_BLUE B_NULL S_NORMAL)
|
||||
#endif
|
||||
#endif /* ELOG_COLOR_ENABLE */
|
||||
|
||||
/* EasyLogger object */
|
||||
static EasyLogger elog;
|
||||
/* every line log's buffer */
|
||||
static char log_buf[ELOG_LINE_BUF_SIZE] = { 0 };
|
||||
/* level output info */
|
||||
static const char *level_output_info[] = {
|
||||
[ELOG_LVL_ASSERT] = "ASSERT/",
|
||||
[ELOG_LVL_ERROR] = "ERROR/",
|
||||
[ELOG_LVL_WARN] = "WARN/",
|
||||
[ELOG_LVL_INFO] = "INFO/",
|
||||
[ELOG_LVL_DEBUG] = "DEBUG/",
|
||||
[ELOG_LVL_VERBOSE] = "VERBOS/",
|
||||
};
|
||||
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
/* color output info */
|
||||
static const char *color_output_info[] = {
|
||||
[ELOG_LVL_ASSERT] = ELOG_COLOR_ASSERT,
|
||||
[ELOG_LVL_ERROR] = ELOG_COLOR_ERROR,
|
||||
[ELOG_LVL_WARN] = ELOG_COLOR_WARN,
|
||||
[ELOG_LVL_INFO] = ELOG_COLOR_INFO,
|
||||
[ELOG_LVL_DEBUG] = ELOG_COLOR_DEBUG,
|
||||
[ELOG_LVL_VERBOSE] = ELOG_COLOR_VERBOSE,
|
||||
};
|
||||
#endif /* ELOG_COLOR_ENABLE */
|
||||
|
||||
static bool get_fmt_enabled(uint8_t level, size_t set);
|
||||
static bool get_fmt_used_and_enabled_u32(uint8_t level, size_t set, uint32_t arg);
|
||||
static bool get_fmt_used_and_enabled_ptr(uint8_t level, size_t set, const char* arg);
|
||||
static void elog_set_filter_tag_lvl_default(void);
|
||||
|
||||
/* EasyLogger assert hook */
|
||||
void (*elog_assert_hook)(const char* expr, const char* func, size_t line);
|
||||
|
||||
extern void elog_port_output(const char *log, size_t size);
|
||||
extern void elog_port_output_lock(void);
|
||||
extern void elog_port_output_unlock(void);
|
||||
|
||||
/**
|
||||
* EasyLogger initialize.
|
||||
*
|
||||
* @return result
|
||||
*/
|
||||
ElogErrCode elog_init(void) {
|
||||
extern ElogErrCode elog_port_init(void);
|
||||
extern ElogErrCode elog_async_init(void);
|
||||
|
||||
ElogErrCode result = ELOG_NO_ERR;
|
||||
|
||||
if (elog.init_ok == true) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* port initialize */
|
||||
result = elog_port_init();
|
||||
if (result != ELOG_NO_ERR) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef ELOG_ASYNC_OUTPUT_ENABLE
|
||||
result = elog_async_init();
|
||||
if (result != ELOG_NO_ERR) {
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* enable the output lock */
|
||||
elog_output_lock_enabled(true);
|
||||
/* output locked status initialize */
|
||||
elog.output_is_locked_before_enable = false;
|
||||
elog.output_is_locked_before_disable = false;
|
||||
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
/* enable text color by default */
|
||||
elog_set_text_color_enabled(true);
|
||||
#endif
|
||||
|
||||
/* set level is ELOG_LVL_VERBOSE */
|
||||
elog_set_filter_lvl(ELOG_LVL_VERBOSE);
|
||||
|
||||
/* set tag_level to default val */
|
||||
elog_set_filter_tag_lvl_default();
|
||||
|
||||
elog.init_ok = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* EasyLogger deinitialize.
|
||||
*
|
||||
*/
|
||||
void elog_deinit(void) {
|
||||
extern ElogErrCode elog_port_deinit(void);
|
||||
extern ElogErrCode elog_async_deinit(void);
|
||||
|
||||
if (!elog.init_ok) {
|
||||
return ;
|
||||
}
|
||||
|
||||
#ifdef ELOG_ASYNC_OUTPUT_ENABLE
|
||||
elog_async_deinit();
|
||||
#endif
|
||||
|
||||
/* port deinitialize */
|
||||
elog_port_deinit();
|
||||
|
||||
elog.init_ok = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* EasyLogger start after initialize.
|
||||
*/
|
||||
void elog_start(void) {
|
||||
if (!elog.init_ok) {
|
||||
return ;
|
||||
}
|
||||
|
||||
/* enable output */
|
||||
elog_set_output_enabled(true);
|
||||
|
||||
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
|
||||
elog_async_enabled(true);
|
||||
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
|
||||
elog_buf_enabled(true);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* EasyLogger stop after initialize.
|
||||
*/
|
||||
void elog_stop(void) {
|
||||
if (!elog.init_ok) {
|
||||
return ;
|
||||
}
|
||||
|
||||
/* disable output */
|
||||
elog_set_output_enabled(false);
|
||||
|
||||
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
|
||||
elog_async_enabled(false);
|
||||
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
|
||||
elog_buf_enabled(false);
|
||||
#endif
|
||||
|
||||
/* show version */
|
||||
log_i("EasyLogger V%s is deinitialize success.", ELOG_SW_VERSION);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set output enable or disable
|
||||
*
|
||||
* @param enabled TRUE: enable FALSE: disable
|
||||
*/
|
||||
void elog_set_output_enabled(bool enabled) {
|
||||
ELOG_ASSERT((enabled == false) || (enabled == true));
|
||||
|
||||
elog.output_enabled = enabled;
|
||||
}
|
||||
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
/**
|
||||
* set log text color enable or disable
|
||||
*
|
||||
* @param enabled TRUE: enable FALSE:disable
|
||||
*/
|
||||
void elog_set_text_color_enabled(bool enabled) {
|
||||
ELOG_ASSERT((enabled == false) || (enabled == true));
|
||||
|
||||
elog.text_color_enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* get log text color enable status
|
||||
*
|
||||
* @return enable or disable
|
||||
*/
|
||||
bool elog_get_text_color_enabled(void) {
|
||||
return elog.text_color_enabled;
|
||||
}
|
||||
#endif /* ELOG_COLOR_ENABLE */
|
||||
|
||||
/**
|
||||
* get output is enable or disable
|
||||
*
|
||||
* @return enable or disable
|
||||
*/
|
||||
bool elog_get_output_enabled(void) {
|
||||
return elog.output_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* set log output format. only enable or disable
|
||||
*
|
||||
* @param level level
|
||||
* @param set format set
|
||||
*/
|
||||
void elog_set_fmt(uint8_t level, size_t set) {
|
||||
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
|
||||
|
||||
elog.enabled_fmt_set[level] = set;
|
||||
}
|
||||
|
||||
/**
|
||||
* set log filter all parameter
|
||||
*
|
||||
* @param level level
|
||||
* @param tag tag
|
||||
* @param keyword keyword
|
||||
*/
|
||||
void elog_set_filter(uint8_t level, const char *tag, const char *keyword) {
|
||||
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
|
||||
|
||||
elog_set_filter_lvl(level);
|
||||
elog_set_filter_tag(tag);
|
||||
elog_set_filter_kw(keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* set log filter's level
|
||||
*
|
||||
* @param level level
|
||||
*/
|
||||
void elog_set_filter_lvl(uint8_t level) {
|
||||
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
|
||||
|
||||
elog.filter.level = level;
|
||||
}
|
||||
|
||||
/**
|
||||
* set log filter's tag
|
||||
*
|
||||
* @param tag tag
|
||||
*/
|
||||
void elog_set_filter_tag(const char *tag) {
|
||||
strncpy(elog.filter.tag, tag, ELOG_FILTER_TAG_MAX_LEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* set log filter's keyword
|
||||
*
|
||||
* @param keyword keyword
|
||||
*/
|
||||
void elog_set_filter_kw(const char *keyword) {
|
||||
strncpy(elog.filter.keyword, keyword, ELOG_FILTER_KW_MAX_LEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* lock output
|
||||
*/
|
||||
void elog_output_lock(void) {
|
||||
if (elog.output_lock_enabled) {
|
||||
elog_port_output_lock();
|
||||
elog.output_is_locked_before_disable = true;
|
||||
} else {
|
||||
elog.output_is_locked_before_enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* unlock output
|
||||
*/
|
||||
void elog_output_unlock(void) {
|
||||
if (elog.output_lock_enabled) {
|
||||
elog_port_output_unlock();
|
||||
elog.output_is_locked_before_disable = false;
|
||||
} else {
|
||||
elog.output_is_locked_before_enable = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set log filter's tag level val to default
|
||||
*/
|
||||
static void elog_set_filter_tag_lvl_default(void)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
for (i =0; i< ELOG_FILTER_TAG_LVL_MAX_NUM; i++){
|
||||
memset(elog.filter.tag_lvl[i].tag, '\0', ELOG_FILTER_TAG_MAX_LEN + 1);
|
||||
elog.filter.tag_lvl[i].level = ELOG_FILTER_LVL_SILENT;
|
||||
elog.filter.tag_lvl[i].tag_use_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filter's level by different tag.
|
||||
* The log on this tag which level is less than it will stop output.
|
||||
*
|
||||
* example:
|
||||
* // the example tag log enter silent mode
|
||||
* elog_set_filter_tag_lvl("example", ELOG_FILTER_LVL_SILENT);
|
||||
* // the example tag log which level is less than INFO level will stop output
|
||||
* elog_set_filter_tag_lvl("example", ELOG_LVL_INFO);
|
||||
* // remove example tag's level filter, all level log will resume output
|
||||
* elog_set_filter_tag_lvl("example", ELOG_FILTER_LVL_ALL);
|
||||
*
|
||||
* @param tag log tag
|
||||
* @param level The filter level. When the level is ELOG_FILTER_LVL_SILENT, the log enter silent mode.
|
||||
* When the level is ELOG_FILTER_LVL_ALL, it will remove this tag's level filer.
|
||||
* Then all level log will resume output.
|
||||
*
|
||||
*/
|
||||
void elog_set_filter_tag_lvl(const char *tag, uint8_t level)
|
||||
{
|
||||
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
|
||||
ELOG_ASSERT(tag != ((void *)0));
|
||||
uint8_t i = 0;
|
||||
|
||||
if (!elog.init_ok) {
|
||||
return;
|
||||
}
|
||||
|
||||
elog_output_lock();
|
||||
/* find the tag in arr */
|
||||
for (i =0; i< ELOG_FILTER_TAG_LVL_MAX_NUM; i++){
|
||||
if (elog.filter.tag_lvl[i].tag_use_flag == true &&
|
||||
!strncmp(tag, elog.filter.tag_lvl[i].tag,ELOG_FILTER_TAG_MAX_LEN)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < ELOG_FILTER_TAG_LVL_MAX_NUM){
|
||||
/* find OK */
|
||||
if (level == ELOG_FILTER_LVL_ALL){
|
||||
/* remove current tag's level filter when input level is the lowest level */
|
||||
elog.filter.tag_lvl[i].tag_use_flag = false;
|
||||
memset(elog.filter.tag_lvl[i].tag, '\0', ELOG_FILTER_TAG_MAX_LEN + 1);
|
||||
elog.filter.tag_lvl[i].level = ELOG_FILTER_LVL_SILENT;
|
||||
} else{
|
||||
elog.filter.tag_lvl[i].level = level;
|
||||
}
|
||||
} else{
|
||||
/* only add the new tag's level filer when level is not ELOG_FILTER_LVL_ALL */
|
||||
if (level != ELOG_FILTER_LVL_ALL){
|
||||
for (i =0; i< ELOG_FILTER_TAG_LVL_MAX_NUM; i++){
|
||||
if (elog.filter.tag_lvl[i].tag_use_flag == false){
|
||||
strncpy(elog.filter.tag_lvl[i].tag, tag, ELOG_FILTER_TAG_MAX_LEN);
|
||||
elog.filter.tag_lvl[i].level = level;
|
||||
elog.filter.tag_lvl[i].tag_use_flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elog_output_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* get the level on tag's level filer
|
||||
*
|
||||
* @param tag tag
|
||||
*
|
||||
* @return It will return the lowest level when tag was not found.
|
||||
* Other level will return when tag was found.
|
||||
*/
|
||||
uint8_t elog_get_filter_tag_lvl(const char *tag)
|
||||
{
|
||||
ELOG_ASSERT(tag != ((void *)0));
|
||||
uint8_t i = 0;
|
||||
uint8_t level = ELOG_FILTER_LVL_ALL;
|
||||
|
||||
if (!elog.init_ok) {
|
||||
return level;
|
||||
}
|
||||
|
||||
elog_output_lock();
|
||||
/* find the tag in arr */
|
||||
for (i =0; i< ELOG_FILTER_TAG_LVL_MAX_NUM; i++){
|
||||
if (elog.filter.tag_lvl[i].tag_use_flag == true &&
|
||||
!strncmp(tag, elog.filter.tag_lvl[i].tag,ELOG_FILTER_TAG_MAX_LEN)){
|
||||
level = elog.filter.tag_lvl[i].level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
elog_output_unlock();
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* output RAW format log
|
||||
*
|
||||
* @param format output format
|
||||
* @param ... args
|
||||
*/
|
||||
void elog_raw_output(const char *format, ...) {
|
||||
va_list args;
|
||||
size_t log_len = 0;
|
||||
int fmt_result;
|
||||
|
||||
/* check output enabled */
|
||||
if (!elog.output_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* args point to the first variable parameter */
|
||||
va_start(args, format);
|
||||
|
||||
/* lock output */
|
||||
elog_output_lock();
|
||||
|
||||
/* package log data to buffer */
|
||||
fmt_result = vsnprintf(log_buf, ELOG_LINE_BUF_SIZE, format, args);
|
||||
|
||||
/* output converted log */
|
||||
if ((fmt_result > -1) && (fmt_result <= ELOG_LINE_BUF_SIZE)) {
|
||||
log_len = fmt_result;
|
||||
} else {
|
||||
log_len = ELOG_LINE_BUF_SIZE;
|
||||
}
|
||||
/* output log */
|
||||
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
|
||||
extern void elog_async_output(uint8_t level, const char *log, size_t size);
|
||||
/* raw log will using assert level */
|
||||
elog_async_output(ELOG_LVL_ASSERT, log_buf, log_len);
|
||||
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
|
||||
extern void elog_buf_output(const char *log, size_t size);
|
||||
elog_buf_output(log_buf, log_len);
|
||||
#else
|
||||
elog_port_output(log_buf, log_len);
|
||||
#endif
|
||||
/* unlock output */
|
||||
elog_output_unlock();
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* output the log
|
||||
*
|
||||
* @param level level
|
||||
* @param tag tag
|
||||
* @param file file name
|
||||
* @param func function name
|
||||
* @param line line number
|
||||
* @param format output format
|
||||
* @param ... args
|
||||
*
|
||||
*/
|
||||
void elog_output(uint8_t level, const char *tag, const char *file, const char *func,
|
||||
const long line, const char *format, ...) {
|
||||
extern const char *elog_port_get_time(void);
|
||||
extern const char *elog_port_get_p_info(void);
|
||||
extern const char *elog_port_get_t_info(void);
|
||||
|
||||
size_t tag_len = strlen(tag), log_len = 0, newline_len = strlen(ELOG_NEWLINE_SIGN);
|
||||
char line_num[ELOG_LINE_NUM_MAX_LEN + 1] = { 0 };
|
||||
char tag_sapce[ELOG_FILTER_TAG_MAX_LEN / 2 + 1] = { 0 };
|
||||
va_list args;
|
||||
int fmt_result;
|
||||
|
||||
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
|
||||
|
||||
/* check output enabled */
|
||||
if (!elog.output_enabled) {
|
||||
return;
|
||||
}
|
||||
/* level filter */
|
||||
if (level > elog.filter.level || level > elog_get_filter_tag_lvl(tag)) {
|
||||
return;
|
||||
} else if (!strstr(tag, elog.filter.tag)) { /* tag filter */
|
||||
return;
|
||||
}
|
||||
/* args point to the first variable parameter */
|
||||
va_start(args, format);
|
||||
/* lock output */
|
||||
elog_output_lock();
|
||||
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
/* add CSI start sign and color info */
|
||||
if (elog.text_color_enabled) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, CSI_START);
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, color_output_info[level]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* package level info */
|
||||
if (get_fmt_enabled(level, ELOG_FMT_LVL)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, level_output_info[level]);
|
||||
}
|
||||
/* package tag info */
|
||||
if (get_fmt_enabled(level, ELOG_FMT_TAG)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, tag);
|
||||
/* if the tag length is less than 50% ELOG_FILTER_TAG_MAX_LEN, then fill space */
|
||||
if (tag_len <= ELOG_FILTER_TAG_MAX_LEN / 2) {
|
||||
memset(tag_sapce, ' ', ELOG_FILTER_TAG_MAX_LEN / 2 - tag_len);
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, tag_sapce);
|
||||
}
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
|
||||
}
|
||||
/* package time, process and thread info */
|
||||
if (get_fmt_enabled(level, ELOG_FMT_TIME | ELOG_FMT_P_INFO | ELOG_FMT_T_INFO)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, "[");
|
||||
/* package time info */
|
||||
if (get_fmt_enabled(level, ELOG_FMT_TIME)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, elog_port_get_time());
|
||||
if (get_fmt_enabled(level, ELOG_FMT_P_INFO | ELOG_FMT_T_INFO)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
|
||||
}
|
||||
}
|
||||
/* package process info */
|
||||
if (get_fmt_enabled(level, ELOG_FMT_P_INFO)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, elog_port_get_p_info());
|
||||
if (get_fmt_enabled(level, ELOG_FMT_T_INFO)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
|
||||
}
|
||||
}
|
||||
/* package thread info */
|
||||
if (get_fmt_enabled(level, ELOG_FMT_T_INFO)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, elog_port_get_t_info());
|
||||
}
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, "] ");
|
||||
}
|
||||
/* package file directory and name, function name and line number info */
|
||||
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_DIR, file) ||
|
||||
get_fmt_used_and_enabled_ptr(level, ELOG_FMT_FUNC, func) ||
|
||||
get_fmt_used_and_enabled_u32(level, ELOG_FMT_LINE, line)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, "(");
|
||||
/* package file info */
|
||||
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_DIR, file)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, file);
|
||||
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_FUNC, func)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, ":");
|
||||
} else if (get_fmt_used_and_enabled_u32(level, ELOG_FMT_LINE, line)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
|
||||
}
|
||||
}
|
||||
/* package line info */
|
||||
if (get_fmt_used_and_enabled_u32(level, ELOG_FMT_LINE, line)) {
|
||||
snprintf(line_num, ELOG_LINE_NUM_MAX_LEN, "%ld", line);
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, line_num);
|
||||
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_FUNC, func)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
|
||||
}
|
||||
}
|
||||
/* package func info */
|
||||
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_FUNC, func)) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, func);
|
||||
|
||||
}
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, ")");
|
||||
}
|
||||
/* package other log data to buffer. '\0' must be added in the end by vsnprintf. */
|
||||
fmt_result = vsnprintf(log_buf + log_len, ELOG_LINE_BUF_SIZE - log_len, format, args);
|
||||
|
||||
va_end(args);
|
||||
/* calculate log length */
|
||||
if ((log_len + fmt_result <= ELOG_LINE_BUF_SIZE) && (fmt_result > -1)) {
|
||||
log_len += fmt_result;
|
||||
} else {
|
||||
/* using max length */
|
||||
log_len = ELOG_LINE_BUF_SIZE;
|
||||
}
|
||||
/* overflow check and reserve some space for CSI end sign and newline sign */
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
if (log_len + (sizeof(CSI_END) - 1) + newline_len > ELOG_LINE_BUF_SIZE) {
|
||||
/* using max length */
|
||||
log_len = ELOG_LINE_BUF_SIZE;
|
||||
/* reserve some space for CSI end sign */
|
||||
log_len -= (sizeof(CSI_END) - 1);
|
||||
#else
|
||||
if (log_len + newline_len > ELOG_LINE_BUF_SIZE) {
|
||||
/* using max length */
|
||||
log_len = ELOG_LINE_BUF_SIZE;
|
||||
#endif /* ELOG_COLOR_ENABLE */
|
||||
/* reserve some space for newline sign */
|
||||
log_len -= newline_len;
|
||||
}
|
||||
/* keyword filter */
|
||||
if (elog.filter.keyword[0] != '\0') {
|
||||
/* add string end sign */
|
||||
log_buf[log_len] = '\0';
|
||||
/* find the keyword */
|
||||
if (!strstr(log_buf, elog.filter.keyword)) {
|
||||
/* unlock output */
|
||||
elog_output_unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
/* add CSI end sign */
|
||||
if (elog.text_color_enabled) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, CSI_END);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* package newline sign */
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, ELOG_NEWLINE_SIGN);
|
||||
/* output log */
|
||||
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
|
||||
extern void elog_async_output(uint8_t level, const char *log, size_t size);
|
||||
elog_async_output(level, log_buf, log_len);
|
||||
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
|
||||
extern void elog_buf_output(const char *log, size_t size);
|
||||
elog_buf_output(log_buf, log_len);
|
||||
#else
|
||||
elog_port_output(log_buf, log_len);
|
||||
#endif
|
||||
/* unlock output */
|
||||
elog_output_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* get format enabled
|
||||
*
|
||||
* @param level level
|
||||
* @param set format set
|
||||
*
|
||||
* @return enable or disable
|
||||
*/
|
||||
static bool get_fmt_enabled(uint8_t level, size_t set) {
|
||||
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
|
||||
|
||||
if (elog.enabled_fmt_set[level] & set) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool get_fmt_used_and_enabled_u32(uint8_t level, size_t set, uint32_t arg) {
|
||||
return arg && get_fmt_enabled(level, set);
|
||||
}
|
||||
static bool get_fmt_used_and_enabled_ptr(uint8_t level, size_t set, const char* arg) {
|
||||
return arg && get_fmt_enabled(level, set);
|
||||
}
|
||||
|
||||
/**
|
||||
* enable or disable logger output lock
|
||||
* @note disable this lock is not recommended except you want output system exception log
|
||||
*
|
||||
* @param enabled true: enable false: disable
|
||||
*/
|
||||
void elog_output_lock_enabled(bool enabled) {
|
||||
elog.output_lock_enabled = enabled;
|
||||
/* it will re-lock or re-unlock before output lock enable */
|
||||
if (elog.output_lock_enabled) {
|
||||
if (!elog.output_is_locked_before_disable && elog.output_is_locked_before_enable) {
|
||||
/* the output lock is unlocked before disable, and the lock will unlocking after enable */
|
||||
elog_port_output_lock();
|
||||
} else if (elog.output_is_locked_before_disable && !elog.output_is_locked_before_enable) {
|
||||
/* the output lock is locked before disable, and the lock will locking after enable */
|
||||
elog_port_output_unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a hook function to EasyLogger assert. It will run when the expression is false.
|
||||
*
|
||||
* @param hook the hook function
|
||||
*/
|
||||
void elog_assert_set_hook(void (*hook)(const char* expr, const char* func, size_t line)) {
|
||||
elog_assert_hook = hook;
|
||||
}
|
||||
|
||||
/**
|
||||
* find the log level
|
||||
* @note make sure the log level is output on each format
|
||||
*
|
||||
* @param log log buffer
|
||||
*
|
||||
* @return log level, found failed will return -1
|
||||
*/
|
||||
int8_t elog_find_lvl(const char *log) {
|
||||
ELOG_ASSERT(log);
|
||||
/* make sure the log level is output on each format */
|
||||
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_ASSERT] & ELOG_FMT_LVL);
|
||||
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_ERROR] & ELOG_FMT_LVL);
|
||||
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_WARN] & ELOG_FMT_LVL);
|
||||
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_INFO] & ELOG_FMT_LVL);
|
||||
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_DEBUG] & ELOG_FMT_LVL);
|
||||
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_VERBOSE] & ELOG_FMT_LVL);
|
||||
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
uint8_t i;
|
||||
size_t csi_start_len = strlen(CSI_START);
|
||||
for(i = 0; i < ELOG_LVL_TOTAL_NUM; i ++) {
|
||||
if (!strncmp(color_output_info[i], log + csi_start_len, strlen(color_output_info[i]))) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
/* found failed */
|
||||
return -1;
|
||||
#else
|
||||
switch (log[0]) {
|
||||
case 'A': return ELOG_LVL_ASSERT;
|
||||
case 'E': return ELOG_LVL_ERROR;
|
||||
case 'W': return ELOG_LVL_WARN;
|
||||
case 'I': return ELOG_LVL_INFO;
|
||||
case 'D': return ELOG_LVL_DEBUG;
|
||||
case 'V': return ELOG_LVL_VERBOSE;
|
||||
default: return -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* find the log tag
|
||||
* @note make sure the log tag is output on each format
|
||||
* @note the tag don't have space in it
|
||||
*
|
||||
* @param log log buffer
|
||||
* @param lvl log level, you can get it by @see elog_find_lvl
|
||||
* @param tag_len found tag length
|
||||
*
|
||||
* @return log tag, found failed will return NULL
|
||||
*/
|
||||
const char *elog_find_tag(const char *log, uint8_t lvl, size_t *tag_len) {
|
||||
const char *tag = NULL, *tag_end = NULL;
|
||||
|
||||
ELOG_ASSERT(log);
|
||||
ELOG_ASSERT(tag_len);
|
||||
ELOG_ASSERT(lvl < ELOG_LVL_TOTAL_NUM);
|
||||
/* make sure the log tag is output on each format */
|
||||
ELOG_ASSERT(elog.enabled_fmt_set[lvl] & ELOG_FMT_TAG);
|
||||
|
||||
#ifdef ELOG_COLOR_ENABLE
|
||||
tag = log + strlen(CSI_START) + strlen(color_output_info[lvl]) + strlen(level_output_info[lvl]);
|
||||
#else
|
||||
tag = log + strlen(level_output_info[lvl]);
|
||||
#endif
|
||||
/* find the first space after tag */
|
||||
if ((tag_end = memchr(tag, ' ', ELOG_FILTER_TAG_MAX_LEN)) != NULL) {
|
||||
*tag_len = tag_end - tag;
|
||||
} else {
|
||||
tag = NULL;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* dump the hex format data to log
|
||||
*
|
||||
* @param name name for hex object, it will show on log header
|
||||
* @param width hex number for every line, such as: 16, 32
|
||||
* @param buf hex buffer
|
||||
* @param size buffer size
|
||||
*/
|
||||
void elog_hexdump(const char *name, uint8_t width, const void *buf, uint16_t size)
|
||||
{
|
||||
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
|
||||
|
||||
uint16_t i, j;
|
||||
uint16_t log_len = 0;
|
||||
const uint8_t *buf_p = buf;
|
||||
char dump_string[8] = {0};
|
||||
int fmt_result;
|
||||
|
||||
if (!elog.output_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* level filter */
|
||||
if (ELOG_LVL_DEBUG > elog.filter.level) {
|
||||
return;
|
||||
} else if (!strstr(name, elog.filter.tag)) { /* tag filter */
|
||||
return;
|
||||
}
|
||||
|
||||
/* lock output */
|
||||
elog_output_lock();
|
||||
|
||||
for (i = 0; i < size; i += width) {
|
||||
/* package header */
|
||||
fmt_result = snprintf(log_buf, ELOG_LINE_BUF_SIZE, "D/HEX %s: %04X-%04X: ", name, i, i + width - 1);
|
||||
/* calculate log length */
|
||||
if ((fmt_result > -1) && (fmt_result <= ELOG_LINE_BUF_SIZE)) {
|
||||
log_len = fmt_result;
|
||||
} else {
|
||||
log_len = ELOG_LINE_BUF_SIZE;
|
||||
}
|
||||
/* dump hex */
|
||||
for (j = 0; j < width; j++) {
|
||||
if (i + j < size) {
|
||||
snprintf(dump_string, sizeof(dump_string), "%02X ", buf_p[i + j]);
|
||||
} else {
|
||||
strncpy(dump_string, " ", sizeof(dump_string));
|
||||
}
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, dump_string);
|
||||
if ((j + 1) % 8 == 0) {
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
|
||||
}
|
||||
}
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
|
||||
/* dump char for hex */
|
||||
for (j = 0; j < width; j++) {
|
||||
if (i + j < size) {
|
||||
snprintf(dump_string, sizeof(dump_string), "%c", __is_print(buf_p[i + j]) ? buf_p[i + j] : '.');
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, dump_string);
|
||||
}
|
||||
}
|
||||
/* overflow check and reserve some space for newline sign */
|
||||
if (log_len + strlen(ELOG_NEWLINE_SIGN) > ELOG_LINE_BUF_SIZE) {
|
||||
log_len = ELOG_LINE_BUF_SIZE - strlen(ELOG_NEWLINE_SIGN);
|
||||
}
|
||||
/* package newline sign */
|
||||
log_len += elog_strcpy(log_len, log_buf + log_len, ELOG_NEWLINE_SIGN);
|
||||
/* do log output */
|
||||
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
|
||||
extern void elog_async_output(uint8_t level, const char *log, size_t size);
|
||||
elog_async_output(ELOG_LVL_DEBUG, log_buf, log_len);
|
||||
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
|
||||
extern void elog_buf_output(const char *log, size_t size);
|
||||
elog_buf_output(log_buf, log_len);
|
||||
#else
|
||||
elog_port_output(log_buf, log_len);
|
||||
#endif
|
||||
}
|
||||
/* unlock output */
|
||||
elog_output_unlock();
|
||||
}
|
||||
79
Core/Bsp/easylogger/src/elog_utils.c
Normal file
79
Core/Bsp/easylogger/src/elog_utils.c
Normal file
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Created by wangb on 25-6-4.
|
||||
//
|
||||
|
||||
#include "elog.h"
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* another copy string function
|
||||
*
|
||||
* @param cur_len current copied log length, max size is ELOG_LINE_BUF_SIZE
|
||||
* @param dst destination
|
||||
* @param src source
|
||||
*
|
||||
* @return copied length
|
||||
*/
|
||||
size_t elog_strcpy(size_t cur_len, char *dst, const char *src) {
|
||||
const char *src_old = src;
|
||||
|
||||
assert(dst);
|
||||
assert(src);
|
||||
|
||||
while (*src != 0) {
|
||||
/* make sure destination has enough space */
|
||||
if (cur_len++ < ELOG_LINE_BUF_SIZE) {
|
||||
*dst++ = *src++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return src - src_old;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy line log split by newline sign. It will copy all log when the newline sign isn't find.
|
||||
*
|
||||
* @param line line log buffer
|
||||
* @param log origin log buffer
|
||||
* @param len origin log buffer length
|
||||
*
|
||||
* @return copy size
|
||||
*/
|
||||
size_t elog_cpyln(char *line, const char *log, size_t len) {
|
||||
size_t newline_len = strlen(ELOG_NEWLINE_SIGN), copy_size = 0;
|
||||
|
||||
assert(line);
|
||||
assert(log);
|
||||
|
||||
while (len--) {
|
||||
*line++ = *log++;
|
||||
copy_size++;
|
||||
if (copy_size >= newline_len && !strncmp(log - newline_len, ELOG_NEWLINE_SIGN, newline_len)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return copy_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will copy memory content from source address to destination
|
||||
* address.
|
||||
*
|
||||
* @param dst the address of destination memory
|
||||
* @param src the address of source memory
|
||||
* @param count the copied length
|
||||
*
|
||||
* @return the address of destination memory
|
||||
*/
|
||||
void *elog_memcpy(void *dst, const void *src, size_t count) {
|
||||
char *tmp = (char *) dst, *s = (char *) src;
|
||||
|
||||
assert(dst);
|
||||
assert(src);
|
||||
|
||||
while (count--)
|
||||
*tmp++ = *s++;
|
||||
|
||||
return dst;
|
||||
}
|
||||
153
Core/Inc/FreeRTOSConfig.h
Normal file
153
Core/Inc/FreeRTOSConfig.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/*
|
||||
* FreeRTOS Kernel V10.0.1
|
||||
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* These parameters and more are described within the 'configuration' section of the
|
||||
* FreeRTOS API documentation available on the FreeRTOS.org web site.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
/* Section where include file can be added */
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Ensure definitions are only used by the compiler, and not by the assembler. */
|
||||
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
extern uint32_t SystemCoreClock;
|
||||
#endif
|
||||
#ifndef CMSIS_device_header
|
||||
#define CMSIS_device_header "stm32f1xx.h"
|
||||
#endif /* CMSIS_device_header */
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||
#define configTICK_RATE_HZ ((TickType_t)1000)
|
||||
#define configMAX_PRIORITIES ( 56 )
|
||||
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
|
||||
#define configTOTAL_HEAP_SIZE ((size_t)30000)
|
||||
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configQUEUE_REGISTRY_SIZE 8
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
/* Software timer definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( 2 )
|
||||
#define configTIMER_QUEUE_LENGTH 10
|
||||
#define configTIMER_TASK_STACK_DEPTH 256
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero
|
||||
to exclude the API function. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 0
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_xQueueGetMutexHolder 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
|
||||
/*
|
||||
* The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
|
||||
* by the application thus the correct define need to be enabled below
|
||||
*/
|
||||
#define USE_FreeRTOS_HEAP_4
|
||||
|
||||
/* Cortex-M specific definitions. */
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||
#else
|
||||
#define configPRIO_BITS 4
|
||||
#endif
|
||||
|
||||
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
||||
function. */
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
|
||||
|
||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
|
||||
|
||||
/* Normal assert() semantics without relying on the provision of an assert.h
|
||||
header file. */
|
||||
/* USER CODE BEGIN 1 */
|
||||
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
||||
standard names. */
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
|
||||
/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
|
||||
|
||||
#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0
|
||||
|
||||
/* USER CODE BEGIN Defines */
|
||||
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
|
||||
/* USER CODE END Defines */
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
52
Core/Inc/dma.h
Normal file
52
Core/Inc/dma.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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__ */
|
||||
|
||||
49
Core/Inc/gpio.h
Normal file
49
Core/Inc/gpio.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/* 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__ */
|
||||
|
||||
52
Core/Inc/i2c.h
Normal file
52
Core/Inc/i2c.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file i2c.h
|
||||
* @brief This file contains all the function prototypes for
|
||||
* the i2c.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 __I2C_H__
|
||||
#define __I2C_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern I2C_HandleTypeDef hi2c1;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_I2C1_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __I2C_H__ */
|
||||
|
||||
99
Core/Inc/main.h
Normal file
99
Core/Inc/main.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/* 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 "stm32f1xx_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 KEY1_Pin GPIO_PIN_0
|
||||
#define KEY1_GPIO_Port GPIOC
|
||||
#define KEY2_Pin GPIO_PIN_1
|
||||
#define KEY2_GPIO_Port GPIOC
|
||||
#define KEY3_Pin GPIO_PIN_2
|
||||
#define KEY3_GPIO_Port GPIOC
|
||||
#define KEY3C3_Pin GPIO_PIN_3
|
||||
#define KEY3C3_GPIO_Port GPIOC
|
||||
#define HX711_DOUT_Pin GPIO_PIN_2
|
||||
#define HX711_DOUT_GPIO_Port GPIOA
|
||||
#define HX711_SCK_Pin GPIO_PIN_3
|
||||
#define HX711_SCK_GPIO_Port GPIOA
|
||||
#define LCD_DC_Pin GPIO_PIN_4
|
||||
#define LCD_DC_GPIO_Port GPIOA
|
||||
#define LCD_RESET_Pin GPIO_PIN_6
|
||||
#define LCD_RESET_GPIO_Port GPIOA
|
||||
#define LCD_CS_Pin GPIO_PIN_4
|
||||
#define LCD_CS_GPIO_Port GPIOC
|
||||
#define LCD_BLK_Pin GPIO_PIN_5
|
||||
#define LCD_BLK_GPIO_Port GPIOC
|
||||
#define LED2_Pin GPIO_PIN_12
|
||||
#define LED2_GPIO_Port GPIOB
|
||||
#define LED1_Pin GPIO_PIN_13
|
||||
#define LED1_GPIO_Port GPIOB
|
||||
#define HC_SR505_IO_Pin GPIO_PIN_14
|
||||
#define HC_SR505_IO_GPIO_Port GPIOB
|
||||
#define M3_IO_Pin GPIO_PIN_15
|
||||
#define M3_IO_GPIO_Port GPIOB
|
||||
#define MOTOR_Pin GPIO_PIN_6
|
||||
#define MOTOR_GPIO_Port GPIOC
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MAIN_H */
|
||||
52
Core/Inc/spi.h
Normal file
52
Core/Inc/spi.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file spi.h
|
||||
* @brief This file contains all the function prototypes for
|
||||
* the spi.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 __SPI_H__
|
||||
#define __SPI_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_SPI1_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SPI_H__ */
|
||||
|
||||
391
Core/Inc/stm32f1xx_hal_conf.h
Normal file
391
Core/Inc/stm32f1xx_hal_conf.h
Normal file
@@ -0,0 +1,391 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_conf.h
|
||||
* @brief HAL configuration file.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017 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 __STM32F1xx_HAL_CONF_H
|
||||
#define __STM32F1xx_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_CAN_MODULE_ENABLED */
|
||||
/*#define HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
/*#define HAL_CEC_MODULE_ENABLED */
|
||||
/*#define HAL_CORTEX_MODULE_ENABLED */
|
||||
/*#define HAL_CRC_MODULE_ENABLED */
|
||||
/*#define HAL_DAC_MODULE_ENABLED */
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
/*#define HAL_ETH_MODULE_ENABLED */
|
||||
/*#define HAL_FLASH_MODULE_ENABLED */
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_I2C_MODULE_ENABLED
|
||||
/*#define HAL_I2S_MODULE_ENABLED */
|
||||
/*#define HAL_IRDA_MODULE_ENABLED */
|
||||
/*#define HAL_IWDG_MODULE_ENABLED */
|
||||
/*#define HAL_NOR_MODULE_ENABLED */
|
||||
/*#define HAL_NAND_MODULE_ENABLED */
|
||||
/*#define HAL_PCCARD_MODULE_ENABLED */
|
||||
/*#define HAL_PCD_MODULE_ENABLED */
|
||||
/*#define HAL_HCD_MODULE_ENABLED */
|
||||
/*#define HAL_PWR_MODULE_ENABLED */
|
||||
/*#define HAL_RCC_MODULE_ENABLED */
|
||||
/*#define HAL_RTC_MODULE_ENABLED */
|
||||
/*#define HAL_SD_MODULE_ENABLED */
|
||||
/*#define HAL_MMC_MODULE_ENABLED */
|
||||
/*#define HAL_SDRAM_MODULE_ENABLED */
|
||||
/*#define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
#define HAL_SPI_MODULE_ENABLED
|
||||
/*#define HAL_SRAM_MODULE_ENABLED */
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
/*#define HAL_USART_MODULE_ENABLED */
|
||||
/*#define HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
|
||||
/* ########################## 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 8000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @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 8000000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */
|
||||
#endif /* LSI_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 */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/* 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 (lowest by default) */
|
||||
#define USE_RTOS 0U
|
||||
#define PREFETCH_ENABLE 1U
|
||||
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2U
|
||||
#define MAC_ADDR1 0U
|
||||
#define MAC_ADDR2 0U
|
||||
#define MAC_ADDR3 0U
|
||||
#define MAC_ADDR4 0U
|
||||
#define MAC_ADDR5 0U
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB 8U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
|
||||
/* DP83848_PHY_ADDRESS Address*/
|
||||
#define DP83848_PHY_ADDRESS 0x01U
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY 0x000000FFU
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY 0x00000FFFU
|
||||
|
||||
#define PHY_READ_TO 0x0000FFFFU
|
||||
#define PHY_WRITE_TO 0x0000FFFFU
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
|
||||
|
||||
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
|
||||
|
||||
/* ################## 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_RCC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#include "Legacy/stm32f1xx_hal_can_legacy.h"
|
||||
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_pccard.h"
|
||||
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_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 /* __STM32F1xx_HAL_CONF_H */
|
||||
|
||||
67
Core/Inc/stm32f1xx_it.h
Normal file
67
Core/Inc/stm32f1xx_it.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_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 __STM32F1xx_IT_H
|
||||
#define __STM32F1xx_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 DebugMon_Handler(void);
|
||||
void DMA1_Channel4_IRQHandler(void);
|
||||
void DMA1_Channel5_IRQHandler(void);
|
||||
void USART1_IRQHandler(void);
|
||||
void TIM8_UP_IRQHandler(void);
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F1xx_IT_H */
|
||||
58
Core/Inc/usart.h
Normal file
58
Core/Inc/usart.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 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 huart5;
|
||||
|
||||
extern UART_HandleTypeDef huart1;
|
||||
|
||||
extern UART_HandleTypeDef huart3;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_UART5_Init(void);
|
||||
void MX_USART1_UART_Init(void);
|
||||
void MX_USART3_UART_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USART_H__ */
|
||||
|
||||
58
Core/Src/dma.c
Normal file
58
Core/Src/dma.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 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_DMA1_CLK_ENABLE();
|
||||
|
||||
/* DMA interrupt init */
|
||||
/* DMA1_Channel4_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
|
||||
/* DMA1_Channel5_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
206
Core/Src/freertos.c
Normal file
206
Core/Src/freertos.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : freertos.c
|
||||
* Description : Code for freertos applications
|
||||
******************************************************************************
|
||||
* @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 "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "main.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "dx_wf_24.h"
|
||||
#include "elog.h"
|
||||
#include "string.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* USER CODE END PTD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PD */
|
||||
#define TAG "Main"
|
||||
/* USER CODE END PD */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PM */
|
||||
|
||||
/* USER CODE END PM */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Variables */
|
||||
|
||||
/* USER CODE END Variables */
|
||||
/* Definitions for defaultTask */
|
||||
osThreadId_t defaultTaskHandle;
|
||||
const osThreadAttr_t defaultTask_attributes = {
|
||||
.name = "defaultTask",
|
||||
.stack_size = 256 * 4,
|
||||
.priority = (osPriority_t) osPriorityNormal,
|
||||
};
|
||||
/* Definitions for wifi_mqtt */
|
||||
osThreadId_t wifi_mqttHandle;
|
||||
const osThreadAttr_t wifi_mqtt_attributes = {
|
||||
.name = "wifi_mqtt",
|
||||
.stack_size = 1024 * 4,
|
||||
.priority = (osPriority_t) osPriorityHigh,
|
||||
};
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN FunctionPrototypes */
|
||||
|
||||
/* USER CODE END FunctionPrototypes */
|
||||
|
||||
void StartDefaultTask(void *argument);
|
||||
void wifi_task_mqtt(void *argument);
|
||||
|
||||
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
|
||||
|
||||
/**
|
||||
* @brief FreeRTOS initialization
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void MX_FREERTOS_Init(void) {
|
||||
/* USER CODE BEGIN Init */
|
||||
easylogger_init(); // 初始化日志系统
|
||||
__enable_irq(); // 开启全局中断
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* USER CODE BEGIN RTOS_MUTEX */
|
||||
/* add mutexes, ... */
|
||||
/* USER CODE END RTOS_MUTEX */
|
||||
|
||||
/* USER CODE BEGIN RTOS_SEMAPHORES */
|
||||
/* add semaphores, ... */
|
||||
/* USER CODE END RTOS_SEMAPHORES */
|
||||
|
||||
/* USER CODE BEGIN RTOS_TIMERS */
|
||||
/* start timers, add new ones, ... */
|
||||
/* USER CODE END RTOS_TIMERS */
|
||||
|
||||
/* USER CODE BEGIN RTOS_QUEUES */
|
||||
/* add queues, ... */
|
||||
/* USER CODE END RTOS_QUEUES */
|
||||
|
||||
/* Create the thread(s) */
|
||||
/* creation of defaultTask */
|
||||
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
|
||||
|
||||
/* creation of wifi_mqtt */
|
||||
wifi_mqttHandle = osThreadNew(wifi_task_mqtt, NULL, &wifi_mqtt_attributes);
|
||||
|
||||
/* USER CODE BEGIN RTOS_THREADS */
|
||||
/* add threads, ... */
|
||||
/* USER CODE END RTOS_THREADS */
|
||||
|
||||
/* USER CODE BEGIN RTOS_EVENTS */
|
||||
/* add events, ... */
|
||||
/* USER CODE END RTOS_EVENTS */
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Header_StartDefaultTask */
|
||||
/**
|
||||
* @brief Function implementing the defaultTask thread.
|
||||
* @param argument: Not used
|
||||
* @retval None
|
||||
*/
|
||||
/* USER CODE END Header_StartDefaultTask */
|
||||
void StartDefaultTask(void *argument)
|
||||
{
|
||||
/* USER CODE BEGIN StartDefaultTask */
|
||||
/* Infinite loop */
|
||||
for (;;) {
|
||||
|
||||
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
|
||||
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
|
||||
HAL_GPIO_TogglePin(MOTOR_GPIO_Port, MOTOR_Pin);
|
||||
osDelay(1000);
|
||||
}
|
||||
/* USER CODE END StartDefaultTask */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Header_wifi_task_mqtt */
|
||||
/**
|
||||
* @brief Function implementing the wifi_mqtt thread.
|
||||
* @param argument: Not used
|
||||
* @retval None
|
||||
*/
|
||||
/* USER CODE END Header_wifi_task_mqtt */
|
||||
void wifi_task_mqtt(void *argument)
|
||||
{
|
||||
/* USER CODE BEGIN wifi_task_mqtt */
|
||||
WIFI_RECV_DMA_Init(); // 初始化 WiFi DMA 接收
|
||||
|
||||
/* 等待模块启动 */
|
||||
elog_i(TAG, "Waiting for WiFi module to start...");
|
||||
osDelay(3000);
|
||||
|
||||
/* 连接MQTT服务器 */
|
||||
uint8_t connect_success = WIFI_Connect_MQTT(
|
||||
"ChinaNet_WBH", // WiFi名称
|
||||
"88888888", // WiFi密码
|
||||
"broker.emqx.io", // MQTT服务器
|
||||
1883, // MQTT端口
|
||||
"STM32_MQTT", // 客户端ID
|
||||
NULL, // MQTT用户名(NULL表示无需认证)
|
||||
NULL, // MQTT密码(NULL表示无需认证)
|
||||
"pet/control" // 订阅主题
|
||||
);
|
||||
|
||||
|
||||
if (connect_success) {
|
||||
elog_i(TAG, "MQTT connection successful!");
|
||||
} else {
|
||||
elog_e(TAG, "MQTT connection failed!");
|
||||
// 可以在这里添加失败处理,如重启模块或重试
|
||||
}
|
||||
|
||||
uint8_t rx_data[WIFI_RX_BUF_SIZE];
|
||||
/* Infinite loop */
|
||||
for (;;) {
|
||||
/* 检查并处理接收数据 */
|
||||
if (wifi.rx_flag) {
|
||||
int len = WIFI_Get_Received_Data(rx_data, sizeof(rx_data));
|
||||
if (len > 0) {
|
||||
// 处理 WiFi 返回数据
|
||||
elog_d(TAG, "WiFi response: %s", rx_data);
|
||||
|
||||
// 检查MQTT消息
|
||||
if (strstr((char*)rx_data, "+MQTTPUBLISH")) {
|
||||
elog_i(TAG, "Received MQTT message!");
|
||||
// TODO: 解析并处理MQTT消息
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
osDelay(100);
|
||||
}
|
||||
/* USER CODE END wifi_task_mqtt */
|
||||
}
|
||||
|
||||
/* Private application code --------------------------------------------------*/
|
||||
/* USER CODE BEGIN Application */
|
||||
|
||||
/* USER CODE END Application */
|
||||
|
||||
108
Core/Src/gpio.c
Normal file
108
Core/Src/gpio.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/* 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 as
|
||||
* Analog
|
||||
* Input
|
||||
* Output
|
||||
* EVENT_OUT
|
||||
* EXTI
|
||||
*/
|
||||
void MX_GPIO_Init(void)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOA, HX711_SCK_Pin|LCD_DC_Pin|LCD_RESET_Pin|GPIO_PIN_8, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOC, LCD_CS_Pin|LCD_BLK_Pin|MOTOR_Pin|GPIO_PIN_7
|
||||
|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, LED2_Pin|LED1_Pin, GPIO_PIN_RESET);
|
||||
|
||||
/*Configure GPIO pins : KEY1_Pin KEY2_Pin KEY3_Pin KEY3C3_Pin */
|
||||
GPIO_InitStruct.Pin = KEY1_Pin|KEY2_Pin|KEY3_Pin|KEY3C3_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : HX711_DOUT_Pin */
|
||||
GPIO_InitStruct.Pin = HX711_DOUT_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(HX711_DOUT_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : HX711_SCK_Pin LCD_DC_Pin LCD_RESET_Pin PA8 */
|
||||
GPIO_InitStruct.Pin = HX711_SCK_Pin|LCD_DC_Pin|LCD_RESET_Pin|GPIO_PIN_8;
|
||||
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);
|
||||
|
||||
/*Configure GPIO pins : LCD_CS_Pin LCD_BLK_Pin MOTOR_Pin PC7
|
||||
PC8 PC9 */
|
||||
GPIO_InitStruct.Pin = LCD_CS_Pin|LCD_BLK_Pin|MOTOR_Pin|GPIO_PIN_7
|
||||
|GPIO_PIN_8|GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : LED2_Pin LED1_Pin */
|
||||
GPIO_InitStruct.Pin = LED2_Pin|LED1_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : HC_SR505_IO_Pin M3_IO_Pin */
|
||||
GPIO_InitStruct.Pin = HC_SR505_IO_Pin|M3_IO_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
||||
114
Core/Src/i2c.c
Normal file
114
Core/Src/i2c.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file i2c.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the I2C 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 "i2c.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
I2C_HandleTypeDef hi2c1;
|
||||
|
||||
/* I2C1 init function */
|
||||
void MX_I2C1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN I2C1_Init 0 */
|
||||
|
||||
/* USER CODE END I2C1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN I2C1_Init 1 */
|
||||
|
||||
/* USER CODE END I2C1_Init 1 */
|
||||
hi2c1.Instance = I2C1;
|
||||
hi2c1.Init.ClockSpeed = 100000;
|
||||
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
|
||||
hi2c1.Init.OwnAddress1 = 0;
|
||||
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||
hi2c1.Init.OwnAddress2 = 0;
|
||||
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN I2C1_Init 2 */
|
||||
|
||||
/* USER CODE END I2C1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(i2cHandle->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 0 */
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**I2C1 GPIO Configuration
|
||||
PB6 ------> I2C1_SCL
|
||||
PB7 ------> I2C1_SDA
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* I2C1 clock enable */
|
||||
__HAL_RCC_I2C1_CLK_ENABLE();
|
||||
/* USER CODE BEGIN I2C1_MspInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
|
||||
{
|
||||
|
||||
if(i2cHandle->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_I2C1_CLK_DISABLE();
|
||||
|
||||
/**I2C1 GPIO Configuration
|
||||
PB6 ------> I2C1_SCL
|
||||
PB7 ------> I2C1_SDA
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
|
||||
|
||||
/* USER CODE BEGIN I2C1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END I2C1_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
234
Core/Src/main.c
Normal file
234
Core/Src/main.c
Normal file
@@ -0,0 +1,234 @@
|
||||
/* 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 "cmsis_os.h"
|
||||
#include "dma.h"
|
||||
#include "i2c.h"
|
||||
#include "spi.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.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 ---------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
void MX_FREERTOS_Init(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Private user code ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 0 */
|
||||
#ifdef __GNUC__
|
||||
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
|
||||
#else
|
||||
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
|
||||
#endif
|
||||
|
||||
PUTCHAR_PROTOTYPE {
|
||||
HAL_UART_Transmit(&huart5, (uint8_t *) &ch, 1, HAL_MAX_DELAY);
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/**
|
||||
* @brief The application entry point.
|
||||
* @retval int
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_DMA_Init();
|
||||
MX_I2C1_Init();
|
||||
MX_SPI1_Init();
|
||||
MX_UART5_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_USART3_UART_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Init scheduler */
|
||||
osKernelInitialize();
|
||||
|
||||
/* Call init function for freertos objects (in cmsis_os2.c) */
|
||||
MX_FREERTOS_Init();
|
||||
|
||||
/* Start scheduler */
|
||||
osKernelStart();
|
||||
|
||||
/* We should never get here as control is now taken by the scheduler */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
|
||||
|
||||
/* 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};
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
|
||||
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
|
||||
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Initializes the CPU, AHB and APB buses clocks
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
|
||||
|
||||
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief Period elapsed callback in non blocking mode
|
||||
* @note This function is called when TIM8 interrupt took place, inside
|
||||
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
|
||||
* a global variable "uwTick" used as application time base.
|
||||
* @param htim : TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* USER CODE BEGIN Callback 0 */
|
||||
|
||||
/* USER CODE END Callback 0 */
|
||||
if (htim->Instance == TIM8) {
|
||||
HAL_IncTick();
|
||||
}
|
||||
/* USER CODE BEGIN Callback 1 */
|
||||
|
||||
/* USER CODE END Callback 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 */
|
||||
115
Core/Src/spi.c
Normal file
115
Core/Src/spi.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file spi.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the SPI 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 "spi.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
SPI_HandleTypeDef hspi1;
|
||||
|
||||
/* SPI1 init function */
|
||||
void MX_SPI1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 0 */
|
||||
|
||||
/* USER CODE END SPI1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 1 */
|
||||
|
||||
/* USER CODE END SPI1_Init 1 */
|
||||
hspi1.Instance = SPI1;
|
||||
hspi1.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi1.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
|
||||
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi1.Init.CRCPolynomial = 10;
|
||||
if (HAL_SPI_Init(&hspi1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN SPI1_Init 2 */
|
||||
|
||||
/* USER CODE END SPI1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(spiHandle->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 0 */
|
||||
/* SPI1 clock enable */
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**SPI1 GPIO Configuration
|
||||
PA5 ------> SPI1_SCK
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
|
||||
{
|
||||
|
||||
if(spiHandle->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_SPI1_CLK_DISABLE();
|
||||
|
||||
/**SPI1 GPIO Configuration
|
||||
PA5 ------> SPI1_SCK
|
||||
PA7 ------> SPI1_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_7);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
88
Core/Src/stm32f1xx_hal_msp.c
Normal file
88
Core/Src/stm32f1xx_hal_msp.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_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_AFIO_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
|
||||
/* System interrupt init*/
|
||||
/* PendSV_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
|
||||
|
||||
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
|
||||
*/
|
||||
__HAL_AFIO_REMAP_SWJ_NOJTAG();
|
||||
|
||||
/* USER CODE BEGIN MspInit 1 */
|
||||
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
130
Core/Src/stm32f1xx_hal_timebase_tim.c
Normal file
130
Core/Src/stm32f1xx_hal_timebase_tim.c
Normal file
@@ -0,0 +1,130 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_timebase_tim.c
|
||||
* @brief HAL time base based on the hardware TIM.
|
||||
******************************************************************************
|
||||
* @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 "stm32f1xx_hal.h"
|
||||
#include "stm32f1xx_hal_tim.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
TIM_HandleTypeDef htim8;
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void TIM8_IRQHandler(void);
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief This function configures the TIM8 as a time base source.
|
||||
* The time source is configured to have 1ms time base with a dedicated
|
||||
* Tick interrupt priority.
|
||||
* @note This function is called automatically at the beginning of program after
|
||||
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
|
||||
* @param TickPriority: Tick interrupt priority.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||
{
|
||||
RCC_ClkInitTypeDef clkconfig;
|
||||
uint32_t uwTimclock = 0U;
|
||||
|
||||
uint32_t uwPrescalerValue = 0U;
|
||||
uint32_t pFLatency;
|
||||
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Enable TIM8 clock */
|
||||
__HAL_RCC_TIM8_CLK_ENABLE();
|
||||
|
||||
/* Get clock configuration */
|
||||
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
|
||||
|
||||
/* Compute TIM8 clock */
|
||||
uwTimclock = HAL_RCC_GetPCLK2Freq();
|
||||
|
||||
/* Compute the prescaler value to have TIM8 counter clock equal to 1MHz */
|
||||
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
|
||||
|
||||
/* Initialize TIM8 */
|
||||
htim8.Instance = TIM8;
|
||||
|
||||
/* Initialize TIMx peripheral as follow:
|
||||
|
||||
+ Period = [(TIM8CLK/1000) - 1]. to have a (1/1000) s time base.
|
||||
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
|
||||
+ ClockDivision = 0
|
||||
+ Counter direction = Up
|
||||
*/
|
||||
htim8.Init.Period = (1000000U / 1000U) - 1U;
|
||||
htim8.Init.Prescaler = uwPrescalerValue;
|
||||
htim8.Init.ClockDivision = 0;
|
||||
htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
|
||||
status = HAL_TIM_Base_Init(&htim8);
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Start the TIM time Base generation in interrupt mode */
|
||||
status = HAL_TIM_Base_Start_IT(&htim8);
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
/* Enable the TIM8 global Interrupt */
|
||||
HAL_NVIC_EnableIRQ(TIM8_UP_IRQn);
|
||||
/* Configure the SysTick IRQ priority */
|
||||
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
||||
{
|
||||
/* Configure the TIM IRQ priority */
|
||||
HAL_NVIC_SetPriority(TIM8_UP_IRQn, TickPriority, 0U);
|
||||
uwTickPrio = TickPriority;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend Tick increment.
|
||||
* @note Disable the tick increment by disabling TIM8 update interrupt.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SuspendTick(void)
|
||||
{
|
||||
/* Disable TIM8 update Interrupt */
|
||||
__HAL_TIM_DISABLE_IT(&htim8, TIM_IT_UPDATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume Tick increment.
|
||||
* @note Enable the tick increment by Enabling TIM8 update interrupt.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ResumeTick(void)
|
||||
{
|
||||
/* Enable TIM8 Update interrupt */
|
||||
__HAL_TIM_ENABLE_IT(&htim8, TIM_IT_UPDATE);
|
||||
}
|
||||
|
||||
228
Core/Src/stm32f1xx_it.c
Normal file
228
Core/Src/stm32f1xx_it.c
Normal file
@@ -0,0 +1,228 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_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 "stm32f1xx_it.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "dx_wf_24.h"
|
||||
/* 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 DMA_HandleTypeDef hdma_usart1_tx;
|
||||
extern DMA_HandleTypeDef hdma_usart1_rx;
|
||||
extern UART_HandleTypeDef huart1;
|
||||
extern TIM_HandleTypeDef htim8;
|
||||
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M3 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 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 */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32F1xx 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_stm32f1xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel4 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel4_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel4_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel4_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_tx);
|
||||
/* USER CODE BEGIN DMA1_Channel4_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel4_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel5 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel5_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel5_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_rx);
|
||||
/* USER CODE BEGIN DMA1_Channel5_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel5_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles USART1 global interrupt.
|
||||
*/
|
||||
void USART1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_IRQn 0 */
|
||||
/* 检查空闲中断标志 */
|
||||
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) {
|
||||
WIFI_UART_IDLE_Callback(&huart1);
|
||||
return; // 已处理,直接返回
|
||||
}
|
||||
/* 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 TIM8 update interrupt.
|
||||
*/
|
||||
void TIM8_UP_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN TIM8_UP_IRQn 0 */
|
||||
|
||||
/* USER CODE END TIM8_UP_IRQn 0 */
|
||||
HAL_TIM_IRQHandler(&htim8);
|
||||
/* USER CODE BEGIN TIM8_UP_IRQn 1 */
|
||||
|
||||
/* USER CODE END TIM8_UP_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
244
Core/Src/syscalls.c
Normal file
244
Core/Src/syscalls.c
Normal file
@@ -0,0 +1,244 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @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__
|
||||
87
Core/Src/sysmem.c
Normal file
87
Core/Src/sysmem.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @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
|
||||
406
Core/Src/system_stm32f1xx.c
Normal file
406
Core/Src/system_stm32f1xx.c
Normal file
@@ -0,0 +1,406 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f1xx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
* 1. This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
|
||||
* factors, AHB/APBx prescalers and Flash settings).
|
||||
* This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32f1xx_xx.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.
|
||||
*
|
||||
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
|
||||
* configure the system clock before to branch to main program.
|
||||
*
|
||||
* 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
|
||||
* the product used), refer to "HSE_VALUE".
|
||||
* When HSE is used as system clock source, directly or through PLL, and you
|
||||
* are using different crystal you have to adapt the HSE value to your own
|
||||
* configuration.
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017-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 stm32f1xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32f1xx.h"
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/*!< Uncomment the following line if you need to use external SRAM */
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/* #define DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/* Note: Following vector table addresses must be defined in line with linker
|
||||
configuration. */
|
||||
/*!< Uncomment the following line if you need to relocate the vector table
|
||||
anywhere in Flash or Sram, else the vector table is kept at the automatic
|
||||
remap of boot address selected */
|
||||
/* #define USER_VECT_TAB_ADDRESS */
|
||||
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table
|
||||
in Sram else user remap will be done in Flash. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#if defined(VECT_TAB_SRAM)
|
||||
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#else
|
||||
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#endif /* VECT_TAB_SRAM */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* This 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 = 8000000;
|
||||
const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
static void SystemInit_ExtMemCtl(void);
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system
|
||||
* Initialize the Embedded Flash Interface, the PLL and update the
|
||||
* SystemCoreClock variable.
|
||||
* @note This function should be used only after reset.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
SystemInit_ExtMemCtl();
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif
|
||||
|
||||
/* Configure the Vector Table location -------------------------------------*/
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
|
||||
#endif /* USER_VECT_TAB_ADDRESS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 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(*) multiplied by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz or 25 MHz, depending on the product used), 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 = 0U, pllmull = 0U, pllsource = 0U;
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
|
||||
#endif /* STM32F105xC */
|
||||
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
uint32_t prediv1factor = 0U;
|
||||
#endif /* STM32F100xB or STM32F100xE */
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00U: /* HSI used as system clock */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04U: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08U: /* PLL used as system clock */
|
||||
|
||||
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
||||
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||
|
||||
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
||||
pllmull = ( pllmull >> 18U) + 2U;
|
||||
|
||||
if (pllsource == 0x00U)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
#else
|
||||
/* HSE selected as PLL clock entry */
|
||||
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
|
||||
{/* HSE oscillator clock divided by 2 */
|
||||
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
pllmull = pllmull >> 18U;
|
||||
|
||||
if (pllmull != 0x0DU)
|
||||
{
|
||||
pllmull += 2U;
|
||||
}
|
||||
else
|
||||
{ /* PLL multiplication factor = PLL input clock * 6.5 */
|
||||
pllmull = 13U / 2U;
|
||||
}
|
||||
|
||||
if (pllsource == 0x00U)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PREDIV1 selected as PLL clock entry */
|
||||
|
||||
/* Get PREDIV1 clock source and division factor */
|
||||
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||
|
||||
if (prediv1source == 0U)
|
||||
{
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PLL2 clock selected as PREDIV1 clock entry */
|
||||
|
||||
/* Get PREDIV2 division factor and PLL2 multiplication factor */
|
||||
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
|
||||
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
|
||||
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
|
||||
}
|
||||
}
|
||||
#endif /* STM32F105xC */
|
||||
break;
|
||||
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute HCLK clock frequency ----------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/**
|
||||
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
|
||||
* before jump to __main
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
/**
|
||||
* @brief Setup the external memory controller.
|
||||
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
|
||||
* This function configures the external SRAM mounted on STM3210E-EVAL
|
||||
* board (STM32 High density devices). This SRAM will be used as program
|
||||
* data memory (including heap and stack).
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit_ExtMemCtl(void)
|
||||
{
|
||||
__IO uint32_t tmpreg;
|
||||
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
|
||||
required, then adjust the Register Addresses */
|
||||
|
||||
/* Enable FSMC clock */
|
||||
RCC->AHBENR = 0x00000114U;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
|
||||
|
||||
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
|
||||
RCC->APB2ENR = 0x000001E0U;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
|
||||
|
||||
(void)(tmpreg);
|
||||
|
||||
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
|
||||
/*---------------- SRAM Address lines configuration -------------------------*/
|
||||
/*---------------- NOE and NWE configuration --------------------------------*/
|
||||
/*---------------- NE3 configuration ----------------------------------------*/
|
||||
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
|
||||
|
||||
GPIOD->CRL = 0x44BB44BBU;
|
||||
GPIOD->CRH = 0xBBBBBBBBU;
|
||||
|
||||
GPIOE->CRL = 0xB44444BBU;
|
||||
GPIOE->CRH = 0xBBBBBBBBU;
|
||||
|
||||
GPIOF->CRL = 0x44BBBBBBU;
|
||||
GPIOF->CRH = 0xBBBB4444U;
|
||||
|
||||
GPIOG->CRL = 0x44BBBBBBU;
|
||||
GPIOG->CRH = 0x444B4B44U;
|
||||
|
||||
/*---------------- FSMC Configuration ---------------------------------------*/
|
||||
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
|
||||
|
||||
FSMC_Bank1->BTCR[4U] = 0x00001091U;
|
||||
FSMC_Bank1->BTCR[5U] = 0x00110212U;
|
||||
}
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
313
Core/Src/usart.c
Normal file
313
Core/Src/usart.c
Normal file
@@ -0,0 +1,313 @@
|
||||
/* 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 huart5;
|
||||
UART_HandleTypeDef huart1;
|
||||
UART_HandleTypeDef huart3;
|
||||
DMA_HandleTypeDef hdma_usart1_tx;
|
||||
DMA_HandleTypeDef hdma_usart1_rx;
|
||||
|
||||
/* UART5 init function */
|
||||
void MX_UART5_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN UART5_Init 0 */
|
||||
|
||||
/* USER CODE END UART5_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN UART5_Init 1 */
|
||||
|
||||
/* USER CODE END UART5_Init 1 */
|
||||
huart5.Instance = UART5;
|
||||
huart5.Init.BaudRate = 115200;
|
||||
huart5.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart5.Init.StopBits = UART_STOPBITS_1;
|
||||
huart5.Init.Parity = UART_PARITY_NONE;
|
||||
huart5.Init.Mode = UART_MODE_TX_RX;
|
||||
huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart5.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
if (HAL_UART_Init(&huart5) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN UART5_Init 2 */
|
||||
|
||||
/* USER CODE END UART5_Init 2 */
|
||||
|
||||
}
|
||||
/* 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;
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART1_Init 2 */
|
||||
|
||||
/* USER CODE END USART1_Init 2 */
|
||||
|
||||
}
|
||||
/* USART3 init function */
|
||||
|
||||
void MX_USART3_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART3_Init 0 */
|
||||
|
||||
/* USER CODE END USART3_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART3_Init 1 */
|
||||
|
||||
/* USER CODE END USART3_Init 1 */
|
||||
huart3.Instance = USART3;
|
||||
huart3.Init.BaudRate = 115200;
|
||||
huart3.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart3.Init.StopBits = UART_STOPBITS_1;
|
||||
huart3.Init.Parity = UART_PARITY_NONE;
|
||||
huart3.Init.Mode = UART_MODE_TX_RX;
|
||||
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||
if (HAL_UART_Init(&huart3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART3_Init 2 */
|
||||
|
||||
/* USER CODE END USART3_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(uartHandle->Instance==UART5)
|
||||
{
|
||||
/* USER CODE BEGIN UART5_MspInit 0 */
|
||||
|
||||
/* USER CODE END UART5_MspInit 0 */
|
||||
/* UART5 clock enable */
|
||||
__HAL_RCC_UART5_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
/**UART5 GPIO Configuration
|
||||
PC12 ------> UART5_TX
|
||||
PD2 ------> UART5_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_12;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN UART5_MspInit 1 */
|
||||
|
||||
/* USER CODE END UART5_MspInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 0 */
|
||||
/* USART1 clock enable */
|
||||
__HAL_RCC_USART1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**USART1 GPIO Configuration
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USART1 DMA Init */
|
||||
/* USART1_TX Init */
|
||||
hdma_usart1_tx.Instance = DMA1_Channel4;
|
||||
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_VERY_HIGH;
|
||||
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);
|
||||
|
||||
/* USART1_RX Init */
|
||||
hdma_usart1_rx.Instance = DMA1_Channel5;
|
||||
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_CIRCULAR;
|
||||
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
|
||||
|
||||
/* USART1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
|
||||
HAL_NVIC_EnableIRQ(USART1_IRQn);
|
||||
/* USER CODE BEGIN USART1_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART3)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART3_MspInit 0 */
|
||||
/* USART3 clock enable */
|
||||
__HAL_RCC_USART3_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**USART3 GPIO Configuration
|
||||
PB10 ------> USART3_TX
|
||||
PB11 ------> USART3_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN USART3_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART3_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
|
||||
if(uartHandle->Instance==UART5)
|
||||
{
|
||||
/* USER CODE BEGIN UART5_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END UART5_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_UART5_CLK_DISABLE();
|
||||
|
||||
/**UART5 GPIO Configuration
|
||||
PC12 ------> UART5_TX
|
||||
PD2 ------> UART5_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_12);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
|
||||
|
||||
/* USER CODE BEGIN UART5_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END UART5_MspDeInit 1 */
|
||||
}
|
||||
else 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
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
|
||||
|
||||
/* USART1 DMA DeInit */
|
||||
HAL_DMA_DeInit(uartHandle->hdmatx);
|
||||
HAL_DMA_DeInit(uartHandle->hdmarx);
|
||||
|
||||
/* USART1 interrupt Deinit */
|
||||
HAL_NVIC_DisableIRQ(USART1_IRQn);
|
||||
/* USER CODE BEGIN USART1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 1 */
|
||||
}
|
||||
else if(uartHandle->Instance==USART3)
|
||||
{
|
||||
/* USER CODE BEGIN USART3_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART3_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART3_CLK_DISABLE();
|
||||
|
||||
/**USART3 GPIO Configuration
|
||||
PB10 ------> USART3_TX
|
||||
PB11 ------> USART3_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
|
||||
|
||||
/* USER CODE BEGIN USART3_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART3_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
Reference in New Issue
Block a user