Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
432 changes: 432 additions & 0 deletions README.md

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions app/app_lowpower.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#include "../app/app_sleep.h"
#include "../examples/telephone/telephone.h"

/* 电源实体按键引脚(CW32L011 平台:GPIOC.13) */
#define POWER_KEY_PORT CW_GPIOC
#define POWER_KEY_PIN GPIO_PIN_13

#define POWER_KEY_IRQn GPIOC_IRQn

typedef enum {
Expand Down
69 changes: 47 additions & 22 deletions dev/inc/module.h
Original file line number Diff line number Diff line change
@@ -1,51 +1,76 @@
#ifndef _MODULE_H
#define _MODULE_H

/**
* @file module.h
* @brief 模组业务逻辑层接口
*
* 本模块负责管理与无线模组(通过 AT 接口通信)相关的业务逻辑:
* - 模组硬件初始化(通过 HAL 层实现,与芯片解耦)
* - 模组中断通知的注册与查询
* - 模组与系统参数的同步
*
* 依赖关系:
* 本层仅依赖 hal_module.h(HAL 接口)和标准库,
* 不包含任何芯片专用头文件,保证可移植性。
*/

#pragma anon_unions

#include <stdint.h>
#include <stdbool.h>
#include "cw32l011_gpio.h"

/**
* @brief 模组状态标志位(与模组 AT+MODEFLAG 响应对应)
*/
typedef struct {
union {
uint8_t bytes[4];
struct {
uint32_t call : 1; // bit 0 - 发起呼叫
uint32_t ring : 1; // bit 1 - 被拨打响铃
uint32_t talk_master : 1; // bit 2 - 作为主机正在通话中
uint32_t talk_slave : 1; // bit 3 - 作为从机正在通话中
uint32_t broadcast_m : 1; // bit 4 - 主机广播
uint32_t broadcast_s : 1; // bit 5 - 从机广播
uint32_t setting : 1; // bit 6 - 进入群组设置
uint32_t invite : 1; // bit 7 - 进入群组邀请模式
uint32_t hangup : 1; // bit 8 - 执行挂断中
uint32_t powerOff : 1; // bit 9 - 模组请求关机
uint32_t reserved : 22; // bit 10-31
uint32_t call : 1; /* bit 0 - 发起呼叫 */
uint32_t ring : 1; /* bit 1 - 被拨打响铃 */
uint32_t talk_master : 1; /* bit 2 - 作为主机正在通话中 */
uint32_t talk_slave : 1; /* bit 3 - 作为从机正在通话中 */
uint32_t broadcast_m : 1; /* bit 4 - 主机广播 */
uint32_t broadcast_s : 1; /* bit 5 - 从机广播 */
uint32_t setting : 1; /* bit 6 - 进入群组设置 */
uint32_t invite : 1; /* bit 7 - 进入群组邀请模式 */
uint32_t hangup : 1; /* bit 8 - 执行挂断中 */
uint32_t powerOff : 1; /* bit 9 - 模组请求关机 */
uint32_t reserved : 22; /* bit 10-31 */
};
};
} modeflag_status_t;

// power实体按键
#define POWER_KEY_PORT CW_GPIOC
#define POWER_KEY_PIN GPIO_PIN_13

// 模组的电源控制
#define POWER_PORT CW_GPIOA
#define POWER_PIN GPIO_PIN_8
/* ============================================================
* 接口声明
* ============================================================ */

// evt
/** @brief 初始化模组业务层(含 HAL 通知引脚初始化) */
void module_init(void);

/** @brief 反初始化模组业务层(含 HAL 通知引脚反初始化) */
void module_deInit(void);

// mode flag notify
/** @brief 查询是否有模组通知待处理(消费一个通知计数) */
bool module_notify_poll(void);

/** @brief 主动投递一个模组通知(可用于软件触发,例如定时轮询) */
void module_notify_post(void *param);

/** @brief 将系统参数同步到模组(发送一组 AT 命令) */
void module_synch(void);

/** @brief 执行模组硬件复位 */
void MODULE_RST(void);

/** @brief 初始化模组中断通知引脚(内部使用) */
void module_notify_init(void);

/** @brief 反初始化模组中断通知引脚(内部使用) */
void module_notify_deInit(void);

/** @brief 唤醒后恢复模组 RST 引脚状态 */
void module_notify_resume(void);

#endif
#endif /* _MODULE_H */
11 changes: 4 additions & 7 deletions dev/src/at.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "../../lib/misc.h"
#include "../../lib/rb.h"

#include "../../drv/inc/drv_uart.h"
#include "../../hal/inc/hal-at.h"
#include "../../config/config.h"

Expand Down Expand Up @@ -430,7 +429,7 @@ static void handle_bat(const char *at_buff)
static void handle_baudrate(const char *at_buff)
{
(void) at_buff; // 未使用
drv_atUart_init(MCU_BAUDRATE_INIT);
hal_at_reinit_baudrate(MCU_BAUDRATE_INIT);
LOG_DEBUG("handle baudrate\n");
}

Expand Down Expand Up @@ -504,12 +503,10 @@ void at_task(void)
case AT_WAIT_RECV:
{
if((millis() - cxt->waitCnt) < cxt->waitTime) {
UartRcv_s *uart = getAtUart();
if(hal_at_is_line_ready()) {
char line_buf[HAL_AT_LINE_BUF_LEN];

if(uart->line_ready) {
char line_buf[UART_LINE_BUF_LEN];

if(drv_atUart_getLine(line_buf, sizeof(line_buf))) {
if(hal_at_get_line(line_buf, sizeof(line_buf))) {
uint16_t line_len = strlen(line_buf);
if((cxt->multi_line_len + line_len) < sizeof(cxt->multi_line_buf)) {
memcpy(cxt->multi_line_buf + cxt->multi_line_len, line_buf, line_len);
Expand Down
93 changes: 45 additions & 48 deletions dev/src/module.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
/*
rst -- modlue MCRL
power out -- module power control
at_isr -- module rsq
*/
/**
* @file module.c
* @brief 模组业务逻辑层实现
*
* 本模块负责:
* 1. 通过 HAL 接口(hal_module.h)完成硬件初始化,不直接操作寄存器
* 2. 维护模组中断通知计数器(中断安全)
* 3. 实现 hal_module_notify_callback(),供 HAL ISR 回调
* 4. 提供 module_synch() 将系统参数下发到模组
*
* 移植说明:
* 本文件无需修改。移植时只需实现 hal/src/hal_module.c 中的硬件接口。
*/
#include <stdint.h>
#include "../inc/module.h"
#include "../../drv/inc/drv_gpio.h"
#include "../../drv/inc/drv_uart.h"
#include "../../lib/misc.h"
#include "../../lib/storage.h"
#include "../../hal/inc/hal_module.h"
#include "../../dev/inc/at.h"
#include "../../dev/inc/sys_tick.h"
#include "../../config/config.h"

/* 模组中断通知计数器(volatile,供中断安全访问) */
static volatile uint32_t module_notify_cnt = 0;

#define ISR_PORT CW_GPIOB
#define ISR_PIN GPIO_PIN_0
/* ============================================================
* 内部辅助函数
* ============================================================ */

static void module_notify_clr(void)
{
Expand All @@ -25,30 +30,41 @@ static void module_notify_clr(void)
__enable_irq();
}

void module_init(void)
/* ============================================================
* HAL 回调实现(由 hal_module.c 中的 ISR 调用)
* ============================================================ */

/**
* @brief 模组中断通知回调
*
* 在 ISR 上下文中被 hal_module.c 调用,递增通知计数。
* hal_module.h 中声明此函数为需由 dev 层实现的回调。
*/
void hal_module_notify_callback(void)
{
module_notify_clr();
module_notify_cnt++;
}

void module_deInit(void)
/* ============================================================
* 对外接口实现
* ============================================================ */

void module_init(void)
{
module_notify_clr();
hal_module_notify_init();
}

void GPIOB_IRQHandler(void)
void module_deInit(void)
{
if(ISR_PORT->ISR & ISR_PIN) {
GPIOB_INTFLAG_CLR(ISR_PIN);
module_notify_cnt++;
}

if(CW_GPIOB->ISR & GPIO_PIN_7) { // 还用作唤醒
GPIOB_INTFLAG_CLR(GPIO_PIN_7);
}
hal_module_notify_deInit();
module_notify_clr();
}

void module_notify_post(void *param)
{
/* param 为定时器事件回调的参数(StartTimerEvent 传入 NULL),暂未使用 */
(void)param;
__disable_irq();
module_notify_cnt++;
__enable_irq();
Expand All @@ -70,39 +86,21 @@ bool module_notify_poll(void)

void module_notify_init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
GPIO_InitStruct.IT = GPIO_IT_RISING;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP;
GPIO_InitStruct.Pins = ISR_PIN;
GPIO_Init(ISR_PORT, &GPIO_InitStruct);

GPIOB_INTFLAG_CLR(ISR_PIN);
NVIC_EnableIRQ(GPIOB_IRQn);
NVIC_SetPriority(GPIOB_IRQn, 0);
hal_module_notify_init();
}

void module_notify_deInit(void)
{
GPIOB_INTFLAG_CLR(ISR_PIN);
NVIC_DisableIRQ(GPIOB_IRQn);
gpio_deinit(GPIO_AT_ISR);
hal_module_notify_deInit();
}

void MODULE_RST(void)
{
gpio_modecfg(GPIO_POWER_OUT, GPIO_MODE_OUT);
gpio_set(GPIO_POWER_OUT, GPIO_SET);

gpio_modecfg(GPIO_RST, GPIO_MODE_OUT);
gpio_set(GPIO_RST, GPIO_RESET);
block_delayMs_4M(20);
gpio_set(GPIO_RST, GPIO_SET);
hal_module_rst();
}

void module_synch(void)
{
SysParam_t *sysParam = getSysParam();

at_send(AT_CMD_SET_SLEEP);
at_send(AT_CMD_VOLUME);
at_send(AT_CMD_GIDSET);
Expand All @@ -113,6 +111,5 @@ void module_synch(void)

void module_notify_resume(void)
{
gpio_modecfg(GPIO_RST, GPIO_MODE_OUT);
gpio_set(GPIO_RST, GPIO_SET);
hal_module_notify_resume();
}
85 changes: 83 additions & 2 deletions hal/inc/hal-at.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,93 @@
#ifndef _HAL_AT_H
#define _HAL_AT_H

/**
* @file hal-at.h
* @brief AT 通信硬件抽象层(HAL)接口定义
*
* 本文件定义了 AT 命令收发所需的硬件操作接口。
* 移植到新芯片/平台时,只需在对应的 hal/src/hal-at.c 中实现这些函数,
* 上层 dev/src/at.c 及应用层代码无需任何修改。
*
* 接口说明:
* - hal_at_init() : 初始化 AT UART 外设
* - hal_at_deInit() : 反初始化 AT UART 外设
* - hal_at_sendData() : 格式化发送 AT 命令字符串
* - hal_at_clear() : 清空 AT 接收缓冲区
* - hal_at_buff() : 获取 AT 接收原始缓冲区指针(可选)
* - hal_at_is_line_ready() : 查询是否已接收到完整的一行数据
* - hal_at_get_line() : 获取并消费一行接收数据
* - hal_at_reinit_baudrate() : 重新初始化 UART 波特率
*/

#include <stdint.h>
#include <stdbool.h>

/** @brief 单行接收缓冲区最大长度(含终止符 '\0') */
#define HAL_AT_LINE_BUF_LEN 100

/**
* @brief 初始化 AT UART 外设
*
* 从系统参数中读取波特率,初始化 UART 硬件,使能接收中断。
*/
void hal_at_init(void);

/**
* @brief 反初始化 AT UART 外设
*
* 禁用中断,关闭 UART 时钟,释放 GPIO 资源。
*/
void hal_at_deInit(void);

/**
* @brief 格式化发送 AT 命令字符串(自动追加 "\r\n")
*
* @param format printf 风格格式字符串
* @param ... 可变参数
*/
void hal_at_sendData(const char *format, ...);
uint8_t *hal_at_buff(void);

/**
* @brief 清空 AT 接收缓冲区
*/
void hal_at_clear(void);

#endif
/**
* @brief 获取 AT 接收原始缓冲区指针
*
* @return 指向内部行缓冲区的指针(只读)
*/
uint8_t *hal_at_buff(void);

/**
* @brief 查询是否已接收到完整的一行数据(以 "\r\n" 结尾)
*
* @return true — 已有完整行数据可读
* @return false — 尚未接收完整行
*/
bool hal_at_is_line_ready(void);

/**
* @brief 获取并消费一行接收数据
*
* 将当前行数据复制到 out_buf,并清空内部行缓冲区。
* 调用前应先通过 hal_at_is_line_ready() 确认数据就绪。
*
* @param out_buf 输出缓冲区
* @param buf_size 输出缓冲区大小(含终止符 '\0')
* @return true — 成功获取一行数据
* @return false — 无数据或参数无效
*/
bool hal_at_get_line(char *out_buf, uint16_t buf_size);

/**
* @brief 重新初始化 UART 为指定波特率
*
* 在波特率切换(AT+BAUDRATE 命令响应)后调用,以新波特率重新配置 UART。
*
* @param baudrate 目标波特率
*/
void hal_at_reinit_baudrate(uint32_t baudrate);

#endif /* _HAL_AT_H */
Loading