00. 目录
文章目录
01. FR801xH概述
FR801xH 系列芯片是面向SOC(片上系统),易于快速开发的低功耗蓝牙芯片。基于 Freqchip 的蓝牙智能固件和协议栈的支持,完全兼容蓝牙 V5.3(LE 模式)协议。同时用户可以基于芯片内置的 ARM CorteM3 嵌入式 32 位高性能单片机开发各种应用程序。
蓝牙智能固件包括 L2CAP 服务层协议、安全管理器 (SM)、属性协议(ATT)、通用属性配置文件 (GATT)和通用访问配置文件(GAP)。此外,还 支持应用程序配置文件,例如接近度、健康温度计、 心率、血压、血糖、人机界面设备(HID)和 SDK (包括驱动程序、OS-API 等)。SDK 还集成了用于网络应用程序的 SIG Mesh 协议。
采用 Freqchip 的创新技术,将 PMU(锂电池充电 器+LDO)、带 XIP 模式的 QSPI FLASH ROM、 I2C、UART、GPIO、ADC、PWM 集成在一块芯片中,为客户提供:
- 竞争力的功耗
- 稳定的蓝牙连接
- 极低的 BOM 成本
02. FR801xH功能框图
03. EXTI相关类型
头文件components/driver/include/driver_exti.h
3.1 ext_int_type_t
enum ext_int_type_t
{
EXT_INT_TYPE_LOW,
EXT_INT_TYPE_HIGH,
EXT_INT_TYPE_POS,
EXT_INT_TYPE_NEG,
};
3.2 exti_mux_t
enum exti_mux_t
{
EXTI_0_PA0 = 0,
EXTI_0_PC0,
EXTI_0_PC7,
EXTI_1_PA1 = 0,
EXTI_1_PC1,
EXTI_1_PC6,
EXTI_2_PA2 = 0,
EXTI_2_PC2,
EXTI_2_PC5,
EXTI_3_PA3 = 0,
EXTI_3_PC3,
EXTI_3_PC4,
EXTI_4_PA4 = 0,
EXTI_4_PC4,
EXTI_4_PC3,
EXTI_5_PA5 = 0,
EXTI_5_PC5,
EXTI_5_PC2,
EXTI_6_PA6 = 0,
EXTI_6_PC6,
EXTI_6_PC1,
EXTI_7_PA7 = 0,
EXTI_7_PC7,
EXTI_7_PC0,
EXTI_8_PB0 = 0,
EXTI_8_PD0,
EXTI_8_PD7,
EXTI_9_PB1 = 0,
EXTI_9_PD1,
EXTI_9_PD6,
EXTI_10_PB2 = 0,
EXTI_10_PD2,
EXTI_10_PD5,
EXTI_11_PB3 = 0,
EXTI_11_PD3,
EXTI_11_PD4,
EXTI_12_PB4 = 0,
EXTI_12_PD4,
EXTI_12_PD3,
EXTI_13_PB5 = 0,
EXTI_13_PD5,
EXTI_13_PD2,
EXTI_14_PB6 = 0,
EXTI_14_PD6,
EXTI_14_PD2,
EXTI_15_PB7 = 0,
EXTI_15_PD7,
EXTI_15_PD1,
};
3.3 exti_channel_t
enum exti_channel_t
{
EXTI_0,
EXTI_1,
EXTI_2,
EXTI_3,
EXTI_4,
EXTI_5,
EXTI_6,
EXTI_7,
EXTI_8,
EXTI_9,
EXTI_10,
EXTI_11,
EXTI_12,
EXTI_13,
EXTI_14,
EXTI_15,
};
04. EXTI相关API
4.1 ext_int_set_port_mux
void ext_int_set_port_mux(enum exti_channel_t exti_channel,enum exti_mux_t exti_io);
功能:
配置外部中断 (External Interrupt - EXTI) 信号源
参数:
exti_channel 外部中断通道
exti_io 连接到上面指定 exti_channel 的物理 GPIO 引脚/信号源
返回值:
None
4.2 ext_int_set_type
void ext_int_set_type(enum exti_channel_t exti_channel, enum ext_int_type_t type);
功能:
配置指定外部中断通道(EXTI Channel)的触发类型
参数:
exti_channel 外部中断通道
type 中断触发类型
返回值:
None
4.3 ext_int_set_control
void ext_int_set_control(enum exti_channel_t exti_channel, uint32_t clk, uint8_t counter);
功能:
配置外部中断相关参数
参数:
exti_channel 外部中断通道
clk 时钟预分频值
counter 计数值 中断源持续次数大于counter才触发中断
返回值:
None
4.4 ext_int_enable
void ext_int_enable(enum exti_channel_t exti_channel);
功能:
使能中断
参数:
exti_channel 外部中断通道
返回值:
None
05. 普通GPIO中断程序示例
示例
static enum ext_int_type_t exti_type;
__attribute__((section("ram_code"))) void exti_isr_ram(void)
{
uint32_t exti_src;
exti_src = ext_int_get_src();
ext_int_clear(exti_src);
co_printf("exti_key:%x\r\n", exti_src);
if (exti_src & BIT(EXTI_12))
{
if (exti_type == EXT_INT_TYPE_LOW)
exti_type = EXT_INT_TYPE_HIGH;
else if (exti_type == EXT_INT_TYPE_HIGH)
exti_type = EXT_INT_TYPE_LOW;
ext_int_set_type(EXTI_12, exti_type);
}
else if (exti_src & BIT(EXTI_13))
{
}
}
void peripheral_demo(void)
{
co_printf("digital exti isr\r\n");
system_set_port_mux(GPIO_PORT_D, GPIO_BIT_4, PORTD4_FUNC_D4);
gpio_set_dir(GPIO_PORT_D, GPIO_BIT_4, GPIO_DIR_IN);
system_set_port_pull(GPIO_PD4, true);
ext_int_set_port_mux(EXTI_12, EXTI_12_PD4);
ext_int_set_type(EXTI_12, EXT_INT_TYPE_LOW);
ext_int_set_control(EXTI_12, 1000, 4);
ext_int_enable(EXTI_12);
system_set_port_mux(GPIO_PORT_D, GPIO_BIT_5, PORTD5_FUNC_D5);
gpio_set_dir(GPIO_PORT_D, GPIO_BIT_5, GPIO_DIR_IN);
system_set_port_pull(GPIO_PD5, true);
ext_int_set_port_mux(EXTI_13, EXTI_13_PD5);
ext_int_set_type(EXTI_13, EXT_INT_TYPE_NEG);
ext_int_set_control(EXTI_13, 1000, 4);
ext_int_enable(EXTI_13);
exti_type = EXT_INT_TYPE_LOW;
NVIC_SetPriority(EXTI_IRQn, 4);
NVIC_EnableIRQ(EXTI_IRQn);
}
运行结果
freqchipuser_entry_after_ble_init
digital exti isr
exti_key:1000
exti_key:1000
exti_key:1000
exti_key:1000
exti_key:2000
exti_key:2000
exti_key:2000
exti_key:2000
exti_key:2000
exti_key:2000
exti_key:2000
exti_key:2000
06. PMU GPIO中断程序示例
程序示例
#include "driver_exti.h"
static enum ext_int_type_t exti_type;
static os_timer_t button_anti_shake_timer;
static uint32_t curr_button_before_anti_shake = 0;
static void button_anti_shake_timeout_handler(void *param)
{
uint32_t pmu_int_pin_setting = ool_read32(PMU_REG_PORTA_TRIG_MASK);
uint32_t gpio_value = ool_read32(PMU_REG_GPIOA_V);
gpio_value &= pmu_int_pin_setting;
gpio_value ^= pmu_int_pin_setting;
if (gpio_value == curr_button_before_anti_shake)
{
gpio_value &= ~GPIO_PC4; // ignore PC4, because of inner usage in lib
if (gpio_value == 0)
{
co_printf("L\r\n");
}
else
{
co_printf("K:%08X\r\n", gpio_value);
}
}
}
__attribute__((section("ram_code"))) void pmu_gpio_isr_ram(void)
{
uint32_t pmu_int_pin_setting = ool_read32(PMU_REG_PORTA_TRIG_MASK);
uint32_t gpio_value = ool_read32(PMU_REG_GPIOA_V);
ool_write32(PMU_REG_PORTA_LAST, gpio_value);
uint32_t tmp = gpio_value & pmu_int_pin_setting;
curr_button_before_anti_shake = tmp ^ pmu_int_pin_setting;
os_timer_start(&button_anti_shake_timer, 10, false);
}
void demo_pmu_exti(void)
{
co_printf("pmu exti isr\r\n");
os_timer_init(&button_anti_shake_timer, button_anti_shake_timeout_handler, NULL);
pmu_set_pin_pull(GPIO_PORT_D, BIT(6) | BIT(7), true); // PD6 low voltage ->isr
// pmu_set_pin_pull(GPIO_PORT_D, BIT(7), false); //PD7 high voltage ->isr
pmu_port_wakeup_func_set(GPIO_PD6 | GPIO_PD7); // PD7 pin should connect to GND with 4.7K resistor
}