修复低功耗时,RX接收不到数据的问题:把RX设置为唤醒口,但是这样子会有个问题,用户发过来的第一包数据会出现错包,利用重发机制可实现正常通讯,MCU端也可以发送数据的时候带上两个字节的0,模组可通过解析器寻头正常识别
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#endif
|
||||
#include "norflash_sfc.h"
|
||||
#include "asm/power/power_port.h"
|
||||
#include "mcu_uart.h"
|
||||
//#include "app_umidigi_chargestore.h"
|
||||
#if TCFG_AUDIO_ANC_ENABLE
|
||||
#include "audio_anc.h"
|
||||
@@ -746,6 +747,17 @@ struct port_wakeup port1 = {
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sleep 时 UART 停,用 PA8 RX 下降沿唤醒(须与 mcu_uart_init 引脚一致)。
|
||||
* 模组产品可直接发协议或前导 0x00;刚醒第一包可能丢/坏,靠协议重试或前导兜底。
|
||||
*/
|
||||
struct port_wakeup port2 = {
|
||||
.pullup_down_enable = ENABLE,
|
||||
.edge = FALLING_EDGE,
|
||||
.filter = PORT_FLT_4ms,
|
||||
.iomap = MCU_UART_RX_PIN,
|
||||
};
|
||||
|
||||
#if TCFG_CHARGE_ENABLE
|
||||
struct port_wakeup charge_port = {
|
||||
.edge = RISING_EDGE, //唤醒方式选择,可选:上升沿\下降沿\双边沿
|
||||
@@ -773,6 +785,7 @@ const struct wakeup_param wk_param = {
|
||||
#if (TCFG_TEST_BOX_ENABLE || TCFG_CHARGESTORE_ENABLE || TCFG_ANC_BOX_ENABLE || TCFG_UMIDIGI_BOX_ENABLE)
|
||||
.port[2] = &port1,
|
||||
#endif
|
||||
.port[3] = &port2, /* UART RX(PA8) 唤醒,软关机时 index=3 关闭 */
|
||||
#if TCFG_CHARGE_ENABLE
|
||||
.aport[0] = &charge_port,
|
||||
.aport[1] = &vbat_port,
|
||||
@@ -991,6 +1004,9 @@ void board_set_soft_poweroff(void)
|
||||
soff_gpio_protect(IO_PORTB_01);
|
||||
#endif
|
||||
|
||||
/* 软关机关闭 UART RX 唤醒,避免误唤醒;勿 protect 该脚 */
|
||||
power_wakeup_index_enable(3, 0);
|
||||
|
||||
board_set_soft_poweroff_common(NULL);
|
||||
|
||||
#if (TCFG_TEST_BOX_ENABLE || TCFG_CHARGESTORE_ENABLE || TCFG_ANC_BOX_ENABLE || TCFG_UMIDIGI_BOX_ENABLE)
|
||||
@@ -1050,6 +1066,10 @@ static void port_wakeup_callback(u8 index, u8 gpio)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (gpio == MCU_UART_RX_PIN) {
|
||||
mcu_uart_rx_keep_awake(); /* 禁止立刻再睡,等待后续串口数据 */
|
||||
}
|
||||
}
|
||||
|
||||
static void aport_wakeup_callback(u8 index, u8 gpio, u8 edge)
|
||||
|
||||
@@ -733,7 +733,7 @@ DAC硬件上的连接方式,可选的配置:
|
||||
//*********************************************************************************//
|
||||
#define TCFG_LOWPOWER_POWER_SEL PWR_LDO15//PWR_LDO15 //电源模式设置,可选DCDC和LDO
|
||||
#define TCFG_LOWPOWER_BTOSC_DISABLE 0 //低功耗模式下BTOSC是否保持
|
||||
/* MCU 串口方案:配合 mcu_bridge LP target,忙时保持唤醒、空闲可进低功耗 */
|
||||
/* MCU 串口方案:RX 下降沿唤醒 + mcu_uart/mcu_bridge LP target,忙时保持唤醒、空闲可进 sleep */
|
||||
#define TCFG_LOWPOWER_LOWPOWER_SEL SLEEP_EN//DEEP_SLEEP_EN//SLEEP_EN//DEEP_SLEEP_EN //低功耗使能,蓝牙&&系统空闲可进入低功耗
|
||||
#define TCFG_LOWPOWER_VDDIOM_LEVEL VDDIOM_VOL_28V //vddiom等级
|
||||
#define TCFG_LOWPOWER_OSC_TYPE OSC_TYPE_LRC //低功耗晶振类型,btosc/lrc
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @brief BLE+MCU 协议桥 P0 实现
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.06
|
||||
* @version V1.2.0
|
||||
* @version V1.3.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.06, cyWu, 首次发布
|
||||
* - V1.1.0, 2026.08.06, cyWu, 改为事件队列 + 独立任务驱动,
|
||||
@@ -11,6 +11,7 @@
|
||||
* 原 sys_timer 回调三方并发访问 s_br 的问题)
|
||||
* - V1.2.0, 2026.08.10, cyWu, 注册 LP target:桥接忙时禁止进低功耗,
|
||||
* 空闲可睡,配合板级 SLEEP_EN 恢复串口方案下的低功耗
|
||||
* - V1.3.0, 2026.08.11, cyWu, 周期递减 UART RX 防睡标志
|
||||
******************************************************************************/
|
||||
|
||||
#include "system/includes.h"
|
||||
@@ -914,6 +915,9 @@ static void mcu_bridge_check_ble_pending(void)
|
||||
*/
|
||||
static void mcu_bridge_periodic(void)
|
||||
{
|
||||
/* 与供应商 demo 主循环一致:周期递减 usr_uart_recieve,非 0 禁止 sleep */
|
||||
mcu_uart_rx_keep_awake_tick();
|
||||
|
||||
mcu_bridge_try_identity();
|
||||
|
||||
if (s_br.identity_adv_pending) {
|
||||
|
||||
@@ -3,20 +3,22 @@
|
||||
* @brief BLE 模组与外部 MCU 的 UART 驱动(PA7 TX / PA8 RX, 9600)
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.06
|
||||
* @version V1.3.0
|
||||
* @version V1.5.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.06, cyWu, 首次发布
|
||||
* - V1.1.0, 2026.08.07, cyWu, TX 使用静态对齐缓冲 + write()
|
||||
* - V1.1.0, 2026.08.07, cyWu, TX 使用静态对齐缓冲 + copy()
|
||||
* - V1.2.0, 2026.08.07, cyWu, 对齐供应商 demo:关闭低功耗
|
||||
* - V1.3.0, 2026.08.07, cyWu, 发送与厂家一致,直接 write(data),去掉 TX 拷贝
|
||||
* - V1.4.0, 2026.08.11, cyWu, sleep 后 RX 靠 GPIO 唤醒;收包/唤醒置位防睡 + LP target
|
||||
* - V1.5.0, 2026.08.11, cyWu, 引脚固定在 init;去掉 USR_JB_UART_RX_PIN 条件编译
|
||||
*
|
||||
* @note 串口收发期间由 mcu_bridge 的 LP target 挡住休眠;
|
||||
* 板级可开 SLEEP_EN,勿在无 LP 保护时直接开 DEEP_SLEEP。
|
||||
* @note sleep 时 UART 停,PA8 RX 作下降沿唤醒;客户可直接发协议或前导 0x00。
|
||||
******************************************************************************/
|
||||
|
||||
#include "system/includes.h"
|
||||
#include "asm/uart_dev.h"
|
||||
#include "asm/gpio.h"
|
||||
#include "asm/power/power_api.h"
|
||||
#include "mcu_uart.h"
|
||||
#include "mcu_bridge.h"
|
||||
#include "mcu_frame.h"
|
||||
@@ -40,6 +42,12 @@ static u8 s_rx_cbuf[MCU_UART_RX_CBUF_SIZE] __attribute__((aligned(4)));
|
||||
static u8 s_rx_tmp[MCU_UART_RX_CBUF_SIZE];
|
||||
static OS_MUTEX s_tx_lock;
|
||||
|
||||
/*
|
||||
* 防睡计数:唤醒口或 UART 收到数据时置 MCU_UART_RX_KEEP_AWAKE_TICKS;
|
||||
* 由 mcu_bridge 主循环周期递减;非 0 时 LP target 禁止进 sleep。
|
||||
*/
|
||||
static volatile u8 s_usr_uart_recieve = 0;
|
||||
|
||||
/*============================================================================*/
|
||||
/* 私有函数 */
|
||||
/*============================================================================*/
|
||||
@@ -63,11 +71,30 @@ static void mcu_uart_rx_task(void *arg)
|
||||
/* timeout=0:无数据时 pend,有 RX/OT 中断后唤醒 */
|
||||
rxcnt = s_uart_bus->read(s_rx_tmp, sizeof(s_rx_tmp), 0);
|
||||
if (rxcnt > 0) {
|
||||
mcu_uart_rx_keep_awake(); /* 真正收到数据,禁止立刻再睡 */
|
||||
log_debug("uart rx cnt=%d", rxcnt);
|
||||
for (int i = 0; i < (int)rxcnt; i++) {
|
||||
log_debug("uart rx data[%d]=%02X", i, s_rx_tmp[i]);
|
||||
}
|
||||
mcu_bridge_on_uart_rx(s_rx_tmp, (uint16_t)rxcnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 低功耗空闲查询:串口防睡标志非 0 则不允许进 sleep
|
||||
* @return 1=可进低功耗,0=保持唤醒
|
||||
*/
|
||||
static u8 mcu_uart_lp_idle_query(void)
|
||||
{
|
||||
return s_usr_uart_recieve ? 0 : 1;
|
||||
}
|
||||
|
||||
REGISTER_LP_TARGET(mcu_uart_lp_target) = {
|
||||
.name = "mcu_uart",
|
||||
.is_idle = mcu_uart_lp_idle_query,
|
||||
};
|
||||
|
||||
/*============================================================================*/
|
||||
/* 公有函数 */
|
||||
/*============================================================================*/
|
||||
@@ -84,8 +111,8 @@ McuUart_Ret_t mcu_uart_init(void)
|
||||
return MCU_UART_OK;
|
||||
}
|
||||
|
||||
u_arg.tx_pin = IO_PORTA_07;
|
||||
u_arg.rx_pin = IO_PORTA_08;
|
||||
u_arg.tx_pin = MCU_UART_TX_PIN;
|
||||
u_arg.rx_pin = MCU_UART_RX_PIN;
|
||||
u_arg.rx_cbuf = s_rx_cbuf;
|
||||
u_arg.rx_cbuf_size = MCU_UART_RX_CBUF_SIZE;
|
||||
u_arg.frame_length = MCU_UART_RX_CBUF_SIZE;
|
||||
@@ -139,3 +166,22 @@ uint8_t mcu_uart_is_ready(void)
|
||||
{
|
||||
return s_initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 置位 UART 防睡标志
|
||||
*/
|
||||
void mcu_uart_rx_keep_awake(void)
|
||||
{
|
||||
s_usr_uart_recieve = MCU_UART_RX_KEEP_AWAKE_TICKS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 周期递减防睡标志
|
||||
*/
|
||||
void mcu_uart_rx_keep_awake_tick(void)
|
||||
{
|
||||
if (s_usr_uart_recieve) {
|
||||
s_usr_uart_recieve--;
|
||||
log_debug("usr_uart_recieve:%d", s_usr_uart_recieve);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,17 @@
|
||||
* @brief BLE 模组与外部 MCU 的 UART 驱动接口(PA7/PA8, 9600)
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.06
|
||||
* @version V1.0.0
|
||||
* @version V1.1.0
|
||||
* @history
|
||||
* - V1.0.0, 2026.08.06, cyWu, 首次发布
|
||||
* - V1.1.0, 2026.08.11, cyWu, 增加 sleep 唤醒防睡接口
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __MCU_UART_H__
|
||||
#define __MCU_UART_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "asm/gpio.h"
|
||||
|
||||
/*============================================================================*/
|
||||
/* 宏定义 */
|
||||
@@ -19,7 +21,14 @@
|
||||
|
||||
#define MCU_UART_BAUD (9600) /**< 协议默认波特率 */
|
||||
#define MCU_UART_RX_CBUF_SIZE (512) /**< DMA 循环缓冲,须为 2 的幂 */
|
||||
/* 引脚:TX=PA7(IO_PORTA_07),RX=PA8(IO_PORTA_08),在 mcu_uart.c 中配置 */
|
||||
#define MCU_UART_TX_PIN IO_PORTA_07 /**< MCU 通信 UART TX */
|
||||
#define MCU_UART_RX_PIN IO_PORTA_08 /**< MCU 通信 UART RX(board 唤醒口须一致) */
|
||||
|
||||
/*
|
||||
* sleep 唤醒或串口收数后保持唤醒的 tick 数(mcu_bridge 约每 200ms 递减一次)。
|
||||
* 取大一些:第一包可能在唤醒过程中丢失,留给对端协议重试窗口(约 3s)。
|
||||
*/
|
||||
#define MCU_UART_RX_KEEP_AWAKE_TICKS (15u)
|
||||
|
||||
/*============================================================================*/
|
||||
/* 错误码 */
|
||||
@@ -59,4 +68,15 @@ McuUart_Ret_t mcu_uart_send(const uint8_t *data, uint16_t len);
|
||||
*/
|
||||
uint8_t mcu_uart_is_ready(void);
|
||||
|
||||
/**
|
||||
* @brief 置位 UART 防睡标志(唤醒回调 / 真正收到数据时调用)
|
||||
* @note 等价供应商 demo:usr_var.usr_uart_recieve = 5
|
||||
*/
|
||||
void mcu_uart_rx_keep_awake(void);
|
||||
|
||||
/**
|
||||
* @brief 主循环周期递减防睡标志(标志非 0 时 LP target 禁止进 sleep)
|
||||
*/
|
||||
void mcu_uart_rx_keep_awake_tick(void);
|
||||
|
||||
#endif /* __MCU_UART_H__ */
|
||||
|
||||
Reference in New Issue
Block a user