修复低功耗时,RX接收不到数据的问题:把RX设置为唤醒口,但是这样子会有个问题,用户发过来的第一包数据会出现错包,利用重发机制可实现正常通讯,MCU端也可以发送数据的时候带上两个字节的0,模组可通过解析器寻头正常识别
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "norflash_sfc.h"
|
#include "norflash_sfc.h"
|
||||||
#include "asm/power/power_port.h"
|
#include "asm/power/power_port.h"
|
||||||
|
#include "mcu_uart.h"
|
||||||
//#include "app_umidigi_chargestore.h"
|
//#include "app_umidigi_chargestore.h"
|
||||||
#if TCFG_AUDIO_ANC_ENABLE
|
#if TCFG_AUDIO_ANC_ENABLE
|
||||||
#include "audio_anc.h"
|
#include "audio_anc.h"
|
||||||
@@ -746,6 +747,17 @@ struct port_wakeup port1 = {
|
|||||||
};
|
};
|
||||||
#endif
|
#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
|
#if TCFG_CHARGE_ENABLE
|
||||||
struct port_wakeup charge_port = {
|
struct port_wakeup charge_port = {
|
||||||
.edge = RISING_EDGE, //唤醒方式选择,可选:上升沿\下降沿\双边沿
|
.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)
|
#if (TCFG_TEST_BOX_ENABLE || TCFG_CHARGESTORE_ENABLE || TCFG_ANC_BOX_ENABLE || TCFG_UMIDIGI_BOX_ENABLE)
|
||||||
.port[2] = &port1,
|
.port[2] = &port1,
|
||||||
#endif
|
#endif
|
||||||
|
.port[3] = &port2, /* UART RX(PA8) 唤醒,软关机时 index=3 关闭 */
|
||||||
#if TCFG_CHARGE_ENABLE
|
#if TCFG_CHARGE_ENABLE
|
||||||
.aport[0] = &charge_port,
|
.aport[0] = &charge_port,
|
||||||
.aport[1] = &vbat_port,
|
.aport[1] = &vbat_port,
|
||||||
@@ -991,6 +1004,9 @@ void board_set_soft_poweroff(void)
|
|||||||
soff_gpio_protect(IO_PORTB_01);
|
soff_gpio_protect(IO_PORTB_01);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* 软关机关闭 UART RX 唤醒,避免误唤醒;勿 protect 该脚 */
|
||||||
|
power_wakeup_index_enable(3, 0);
|
||||||
|
|
||||||
board_set_soft_poweroff_common(NULL);
|
board_set_soft_poweroff_common(NULL);
|
||||||
|
|
||||||
#if (TCFG_TEST_BOX_ENABLE || TCFG_CHARGESTORE_ENABLE || TCFG_ANC_BOX_ENABLE || TCFG_UMIDIGI_BOX_ENABLE)
|
#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;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gpio == MCU_UART_RX_PIN) {
|
||||||
|
mcu_uart_rx_keep_awake(); /* 禁止立刻再睡,等待后续串口数据 */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void aport_wakeup_callback(u8 index, u8 gpio, u8 edge)
|
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_POWER_SEL PWR_LDO15//PWR_LDO15 //电源模式设置,可选DCDC和LDO
|
||||||
#define TCFG_LOWPOWER_BTOSC_DISABLE 0 //低功耗模式下BTOSC是否保持
|
#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_LOWPOWER_SEL SLEEP_EN//DEEP_SLEEP_EN//SLEEP_EN//DEEP_SLEEP_EN //低功耗使能,蓝牙&&系统空闲可进入低功耗
|
||||||
#define TCFG_LOWPOWER_VDDIOM_LEVEL VDDIOM_VOL_28V //vddiom等级
|
#define TCFG_LOWPOWER_VDDIOM_LEVEL VDDIOM_VOL_28V //vddiom等级
|
||||||
#define TCFG_LOWPOWER_OSC_TYPE OSC_TYPE_LRC //低功耗晶振类型,btosc/lrc
|
#define TCFG_LOWPOWER_OSC_TYPE OSC_TYPE_LRC //低功耗晶振类型,btosc/lrc
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @brief BLE+MCU 协议桥 P0 实现
|
* @brief BLE+MCU 协议桥 P0 实现
|
||||||
* @author cyWu <1917507415@qq.com>
|
* @author cyWu <1917507415@qq.com>
|
||||||
* @date 2026.08.06
|
* @date 2026.08.06
|
||||||
* @version V1.2.0
|
* @version V1.3.0
|
||||||
* @history
|
* @history
|
||||||
* - V1.0.0, 2026.08.06, cyWu, 首次发布
|
* - V1.0.0, 2026.08.06, cyWu, 首次发布
|
||||||
* - V1.1.0, 2026.08.06, cyWu, 改为事件队列 + 独立任务驱动,
|
* - V1.1.0, 2026.08.06, cyWu, 改为事件队列 + 独立任务驱动,
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
* 原 sys_timer 回调三方并发访问 s_br 的问题)
|
* 原 sys_timer 回调三方并发访问 s_br 的问题)
|
||||||
* - V1.2.0, 2026.08.10, cyWu, 注册 LP target:桥接忙时禁止进低功耗,
|
* - V1.2.0, 2026.08.10, cyWu, 注册 LP target:桥接忙时禁止进低功耗,
|
||||||
* 空闲可睡,配合板级 SLEEP_EN 恢复串口方案下的低功耗
|
* 空闲可睡,配合板级 SLEEP_EN 恢复串口方案下的低功耗
|
||||||
|
* - V1.3.0, 2026.08.11, cyWu, 周期递减 UART RX 防睡标志
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "system/includes.h"
|
#include "system/includes.h"
|
||||||
@@ -914,6 +915,9 @@ static void mcu_bridge_check_ble_pending(void)
|
|||||||
*/
|
*/
|
||||||
static void mcu_bridge_periodic(void)
|
static void mcu_bridge_periodic(void)
|
||||||
{
|
{
|
||||||
|
/* 与供应商 demo 主循环一致:周期递减 usr_uart_recieve,非 0 禁止 sleep */
|
||||||
|
mcu_uart_rx_keep_awake_tick();
|
||||||
|
|
||||||
mcu_bridge_try_identity();
|
mcu_bridge_try_identity();
|
||||||
|
|
||||||
if (s_br.identity_adv_pending) {
|
if (s_br.identity_adv_pending) {
|
||||||
|
|||||||
@@ -3,20 +3,22 @@
|
|||||||
* @brief BLE 模组与外部 MCU 的 UART 驱动(PA7 TX / PA8 RX, 9600)
|
* @brief BLE 模组与外部 MCU 的 UART 驱动(PA7 TX / PA8 RX, 9600)
|
||||||
* @author cyWu <1917507415@qq.com>
|
* @author cyWu <1917507415@qq.com>
|
||||||
* @date 2026.08.06
|
* @date 2026.08.06
|
||||||
* @version V1.3.0
|
* @version V1.5.0
|
||||||
* @history
|
* @history
|
||||||
* - V1.0.0, 2026.08.06, cyWu, 首次发布
|
* - 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.2.0, 2026.08.07, cyWu, 对齐供应商 demo:关闭低功耗
|
||||||
* - V1.3.0, 2026.08.07, cyWu, 发送与厂家一致,直接 write(data),去掉 TX 拷贝
|
* - 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 挡住休眠;
|
* @note sleep 时 UART 停,PA8 RX 作下降沿唤醒;客户可直接发协议或前导 0x00。
|
||||||
* 板级可开 SLEEP_EN,勿在无 LP 保护时直接开 DEEP_SLEEP。
|
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "system/includes.h"
|
#include "system/includes.h"
|
||||||
#include "asm/uart_dev.h"
|
#include "asm/uart_dev.h"
|
||||||
#include "asm/gpio.h"
|
#include "asm/gpio.h"
|
||||||
|
#include "asm/power/power_api.h"
|
||||||
#include "mcu_uart.h"
|
#include "mcu_uart.h"
|
||||||
#include "mcu_bridge.h"
|
#include "mcu_bridge.h"
|
||||||
#include "mcu_frame.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 u8 s_rx_tmp[MCU_UART_RX_CBUF_SIZE];
|
||||||
static OS_MUTEX s_tx_lock;
|
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 中断后唤醒 */
|
/* timeout=0:无数据时 pend,有 RX/OT 中断后唤醒 */
|
||||||
rxcnt = s_uart_bus->read(s_rx_tmp, sizeof(s_rx_tmp), 0);
|
rxcnt = s_uart_bus->read(s_rx_tmp, sizeof(s_rx_tmp), 0);
|
||||||
if (rxcnt > 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);
|
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;
|
return MCU_UART_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
u_arg.tx_pin = IO_PORTA_07;
|
u_arg.tx_pin = MCU_UART_TX_PIN;
|
||||||
u_arg.rx_pin = IO_PORTA_08;
|
u_arg.rx_pin = MCU_UART_RX_PIN;
|
||||||
u_arg.rx_cbuf = s_rx_cbuf;
|
u_arg.rx_cbuf = s_rx_cbuf;
|
||||||
u_arg.rx_cbuf_size = MCU_UART_RX_CBUF_SIZE;
|
u_arg.rx_cbuf_size = MCU_UART_RX_CBUF_SIZE;
|
||||||
u_arg.frame_length = 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;
|
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)
|
* @brief BLE 模组与外部 MCU 的 UART 驱动接口(PA7/PA8, 9600)
|
||||||
* @author cyWu <1917507415@qq.com>
|
* @author cyWu <1917507415@qq.com>
|
||||||
* @date 2026.08.06
|
* @date 2026.08.06
|
||||||
* @version V1.0.0
|
* @version V1.1.0
|
||||||
* @history
|
* @history
|
||||||
* - V1.0.0, 2026.08.06, cyWu, 首次发布
|
* - V1.0.0, 2026.08.06, cyWu, 首次发布
|
||||||
|
* - V1.1.0, 2026.08.11, cyWu, 增加 sleep 唤醒防睡接口
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#ifndef __MCU_UART_H__
|
#ifndef __MCU_UART_H__
|
||||||
#define __MCU_UART_H__
|
#define __MCU_UART_H__
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "asm/gpio.h"
|
||||||
|
|
||||||
/*============================================================================*/
|
/*============================================================================*/
|
||||||
/* 宏定义 */
|
/* 宏定义 */
|
||||||
@@ -19,7 +21,14 @@
|
|||||||
|
|
||||||
#define MCU_UART_BAUD (9600) /**< 协议默认波特率 */
|
#define MCU_UART_BAUD (9600) /**< 协议默认波特率 */
|
||||||
#define MCU_UART_RX_CBUF_SIZE (512) /**< DMA 循环缓冲,须为 2 的幂 */
|
#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);
|
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__ */
|
#endif /* __MCU_UART_H__ */
|
||||||
|
|||||||
Reference in New Issue
Block a user