Board 层 API 是涂鸦抽象芯片硬件外设和封装的标准接口。你可以调用这些 API 来使用相应外设,快速实现产品功能,也可以根据需要直接调用原厂外设接口。
Board 层功能模块列表如下:
名称 | API 文件 | 功能说明 |
---|---|---|
PIN | ty_pin.h | GPIO 外设相关函数使用说明 |
PWM | ty_pwm.h | PWM 外设相关函数使用说明 |
ADC | ty_adc.h | ADC 外设相关函数使用说明 |
I2C | ty_i2c.h | I2C 外设相关函数使用说明 |
FLASH | ty_flash.h | Flash 外设相关函数使用说明 |
API Demo 获取:tuya_ble_board_api_demo
一. PIN
1.1 文件说明
PIN 相关 API 位于 ty_pin.h
芯片平台关联的驱动代码位于文件中 ty_pin_xxxx.c
文件中。
tuya_ble_sdk_demo └── board ├── include | └── ty_pin.h ├── xxxx /* xxxx 芯片平台,如 TLSR825x */ | └── ty_board_xxxx /* xxxx 对于芯片平台,如 ty_board_tlsr825x */ | └── ty_pin_xxxx.c /* xxxx 芯片平台,如 ty_pin_tlsr825x.c */ └── board.h
tuya_board_api_demo 的 PIN Demo 文件结构如下:
tuya_ble_sdk_demo ├── app /* API 应用示例 */ | ├── include | | └── ty_board_demo | | | ├── demo_config.h /* demo 配置文件 */ | | | └── ty_pin_demo.h /* pin 模块示例代码 */ | | ├── tuya_ble_board_api_demo.h /* board api 示例程序入口 */ | | └── tuya_ble_sdk_demo.h /* tuya_ble_sdk 应用入口 */ | └── src | ├── ty_board_demo | | └── ty_pin_demo.c /* pin 模块示例代码 */ | ├── tuya_ble_board_api_demo.c /* board api 示例程序入口 */ | └── tuya_ble_sdk_demo.c /* tuya_ble_sdk 应用入口 */ └── board /* 部分 API 修改示例 */
修改 demo_config.h
可以切换到文件 PIN 模块示例程序:
#define BOARD_API_DEMO BOARD_API_PIN
1.2 API 列表
函数名称 | 功能描述 |
---|---|
ty_pin_init | 引脚模式的初始化 |
ty_pin_set | 设置引脚电平 |
ty_pin_get | 读取引脚电平 |
ty_pin_control | 引脚相关控制 |
ty_pin_uninit | 关闭引脚模块 |
1.3 API 说明
ty_pin_init
函数名 | ty_pin_init |
---|---|
uint32_t ty_pin_init(uint8_t pin, ty_pin_mode_t mode); | |
引脚模式的初始化 | |
pin [in]:引脚编号mode [in]:引脚模式,由 ty_pin_mode_t 类型定义 | |
0 :成功;其他:失败 |
|
函数内容、参数和返回值可根据芯片平台按需补充或修改 |
ty_pin_set
函数名 | ty_pin_set |
---|---|
uint32_t ty_pin_set(uint8_t pin, ty_pin_level_t level); | |
设置引脚电平 | |
pin [in]:引脚编号level [in]:引脚电平,由 ty_pin_level_t 类型定义 | |
0 :成功;其他:失败 |
|
可根据芯片平台按需补充或修改函数内容、参数及返回值 |
ty_pin_get
函数名 | ty_pin_get |
---|---|
uint32_t ty_pin_get(uint8_t pin, ty_pin_level_t* p_level); | |
读取引脚的电平 | |
pin [in]:引脚编号p_level [out]:引脚电平,由 ty_pin_level_t 类型定义 | |
0 :成功;其他:失败 |
|
可根据芯片平台按需补充或修改函数内容、参数及返回值 |
ty_pin_control
函数名 | ty_pin_control |
---|---|
uint32_t ty_pin_control(uint8_t pin, uint8_t cmd, void* arg); | |
控制引脚 | |
pin [in]:引脚编号cmd [in]:控制命令arg [in]:命令参数 | |
0 :成功;其他:失败 |
|
可根据芯片平台按需补充或修改函数内容、参数及返回值 |
ty_pin_uninit
函数名 | ty_pin_uninit |
---|---|
uint32_t ty_pin_uninit(uint8_t pin, ty_pin_mode_t mode); | |
设置引脚的电平 | |
pin [in]:引脚编号mode [in]:引脚模式 | |
0 :成功;其他:失败 |
|
可根据芯片平台按需补充或修改函数内容、参数及返回值改 |
1.4 数据结构
ty_pin_mode_t
/* ! 与 SDK 中不一致是因为此处省略了部分代码 */
typedef enum {
//PU -> pull up
//PD -> pull dowm
//FL -> floating
//PP -> push pull
//OD -> open drain
//hiz -> high-impedance level
/* 输入 */
TY_PIN_MODE_IN_PU, /* 上拉输入 */
TY_PIN_MODE_IN_PD, /* 下拉输入 */
TY_PIN_MODE_IN_FL, /* 浮空输入 */
/* 外部中断 */
TY_PIN_MODE_IN_IRQ_RISE, /* 上升沿触发 */
TY_PIN_MODE_IN_IRQ_FALL, /* 下降沿触发 */
TY_PIN_MODE_IN_IRQ_RISE_FALL, /* 双边沿触发 */
TY_PIN_MODE_IN_IRQ_LOW, /* 低电平触发 */
TY_PIN_MODE_IN_IRQ_HIGH, /* 高电平触发 */
/* 推挽输出 */
TY_PIN_MODE_OUT_PP_LOW, /* 初期低电平 */
TY_PIN_MODE_OUT_PP_HIGH, /* 初期高电平 */
/* 推挽输出,带上拉 */
TY_PIN_MODE_OUT_PP_PU_LOW, /* 初期低电平 */
TY_PIN_MODE_OUT_PP_PU_HIGH, /* 初期高电平 */
/* 推挽输出,带下拉 */
TY_PIN_MODE_OUT_PP_PD_LOW, /* 初期低电平 */
TY_PIN_MODE_OUT_PP_PD_HIGH, /* 初期高电平 */
/* 开漏输出 */
TY_PIN_MODE_OUT_OD_LOW, /* 初期低电平 */
TY_PIN_MODE_OUT_OD_HIZ, /* 初期高阻态 */
/* 开漏输出,带上拉 */
TY_PIN_MODE_OUT_OD_PU_LOW, /* 初期低电平 */
TY_PIN_MODE_OUT_OD_PU_HIGH, /* 初期高电平 */
} ty_pin_mode_t;
ty_pin_level_t
typedef enum {
TY_PIN_LOW = 0, /* 低电平 */
TY_PIN_HIGH /* 高电平 */
} ty_pin_level_t;
1.5 API 示例
以 TLSR825x 平台为例,可参考以下代码补充 PIN 模块的 API 函数,或者直接在应用代码中调用芯片原厂提供的 API 来实现相关功能。
/* ! pin的类型默认为uint8_t,需要根据芯片平台进行修改 */
uint32_t ty_pin_init(uint16_t pin, ty_pin_mode_t mode);
uint32_t ty_pin_set(uint16_t pin, ty_pin_level_t level);
uint32_t ty_pin_get(uint16_t pin, ty_pin_level_t* p_level);
uint32_t ty_pin_init(uint16_t pin, ty_pin_mode_t mode)
{
gpio_set_func(pin, AS_GPIO);
if ((mode & TY_PIN_INOUT_MASK) <= TY_PIN_IN_IRQ) {
gpio_set_input_en(pin, 1);
gpio_set_output_en(pin, 0);
} else {
gpio_set_input_en(pin, 0);
gpio_set_output_en(pin, 1);
}
switch (mode) {
case TY_PIN_MODE_IN_PU:
gpio_setup_up_down_resistor(pin, PM_PIN_PULLUP_10K);
break;
case TY_PIN_MODE_IN_PD:
gpio_setup_up_down_resistor(pin, PM_PIN_PULLDOWN_100K);
break;
case TY_PIN_MODE_IN_FL:
gpio_setup_up_down_resistor(pin, PM_PIN_UP_DOWN_FLOAT);
break;
case TY_PIN_MODE_OUT_PP_LOW:
gpio_write(pin, 0);
break;
case TY_PIN_MODE_OUT_PP_HIGH:
gpio_write(pin, 1);
break;
default:
break;
}
#if(GPIO_WAKEUP_MODULE_POLARITY == 1)
cpu_set_gpio_wakeup (WAKEUP_MODULE_GPIO, Level_High, 1);
GPIO_WAKEUP_MODULE_LOW;
#else
cpu_set_gpio_wakeup (WAKEUP_MODULE_GPIO, Level_Low, 1);
GPIO_WAKEUP_MODULE_HIGH;
#endif
return 0;
}
uint32_t ty_pin_set(uint16_t pin, ty_pin_level_t level)
{
gpio_write(pin, level);
return 0;
}
uint32_t ty_pin_get(uint16_t pin, ty_pin_level_t* p_level)
{
*p_level = gpio_read(pin);
return 0;
}
1.6 应用示例
按键按下 (Low),LED 点亮 (High);按键释放 (High),LED 熄灭 (Low)。
以 TLSR825x 平台为例:
#include "ty_pin_demo.h"
#include "ty_pin.h"
#include "tuya_ble_log.h"
#include "tuya_ble_port.h"
/*********************************************************** ************************micro define************************ ***********************************************************/
#define KEY_PIN GPIO_PA0
#define LED_PIN GPIO_PD7
#define KEY_SCAN_TIME_MS 10
/*********************************************************** ***********************variable define********************** ***********************************************************/
static tuya_ble_timer_t sg_pin_timer;
/*********************************************************** ***********************function define********************** ***********************************************************/
/** * @brief pin timer callback * @param none * @return none */
void __pin_timer_cb(void)
{
ty_pin_level_t pin_level = 0;
ty_pin_get(KEY_PIN, &pin_level);
ty_pin_set(LED_PIN, !pin_level);
}
/** * @brief ty_pin api demo init * @param none * @return none */
void ty_pin_demo_init(void)
{
uint32_t res;
/* key pin init */
res = ty_pin_init(KEY_PIN, TY_PIN_MODE_IN_PU);
if (res) {
TUYA_APP_LOG_ERROR("ty_pin_init KEY_PIN failed, error code: %d", res);
return;
}
/* led pin init */
res = ty_pin_init(LED_PIN, TY_PIN_MODE_OUT_PP_LOW);
if (res) {
TUYA_APP_LOG_ERROR("ty_pin_init KEY_PIN failed, error code: %d", res);
return;
}
/* timer init */
tuya_ble_timer_create(&sg_pin_timer, KEY_SCAN_TIME_MS, TUYA_BLE_TIMER_REPEATED, (tuya_ble_timer_handler_t)__pin_timer_cb);
tuya_ble_timer_start(sg_pin_timer);
}
二. PWM
2.1 文件说明
PWM 相关 API 位于 ty_pwm.h
文件中,芯片平台关联的驱动代码位于 ty_pwm_xxxx.c
文件中。
tuya_ble_sdk_demo
└── board
├── include
| └── ty_pwm.h
├── xxxx /* xxxx 为芯片平台,如 TLSR825x */
| └── ty_board_xxxx /* xxxx 为芯片平台,如 ty_board_tlsr825x */
| └── ty_pwm_xxxx.c /* xxxx 为芯片平台,如 ty_pwm_tlsr825x.c */
└── board.h
tuya_board_api_demo 的 PWM Demo 文件结构如下:
tuya_ble_sdk_demo
├── app /* API 应用示例 */
| ├── include
| | └── ty_board_demo
| | | ├── demo_config.h /* demo 配置文件 */
| | | └── ty_pwm_demo.h /* pwm 模块示例代码 */
| | ├── tuya_ble_board_api_demo.h /* board api 示例程序入口 */
| | └── tuya_ble_sdk_demo.h /* tuya_ble_sdk 应用入口 */
| └── src
| ├── ty_board_demo
| | └── ty_pwm_demo.c /* pwm 模块示例代码 */
| ├── tuya_ble_board_api_demo.c /* board api 示例程序入口 */
| └── tuya_ble_sdk_demo.c /* tuya_ble_sdk 应用入口 */
└── board /* 部分 API 修改示例 */
修改 demo_config.h
文件即可切换到 PWM 模块示例程序:
#define BOARD_API_DEMO BOARD_API_PWM
2.2 API 列表
函数名称 | 功能描述 |
---|---|
ty_pwm_init | 初始化 PWM 模块 |
ty_pwm_start | 启动 PWM 输出 |
ty_pwm_stop | 停止 PWM 输出 |
ty_pwm_control | 控制 PWM 模块 |
ty_pwm_uninit | 关闭 PWM 模块 |
2.3 API 说明
ty_pwm_init
函数名 | ty_pwm_init |
---|---|
uint32_t ty_pwm_init(ty_pwm_t* p_pwm); | |
初始化 PWM 模块 | |
p_pwm [in]:pwm 参数,由 ty_pwm_t 类型定义 | |
0 :成功;其他:失败 |
|
可根据芯片平台按需补充或修改函数内容、参数及返回值 |
ty_pwm_start
函数名 | ty_pwm_start |
---|---|
uint32_t ty_pwm_start(ty_pwm_t* p_pwm); | |
启动 PWM 输出 | |
p_pwm [in]:pwm 参数,由 ty_pwm_t 类型定义 | |
0 :成功;其他:失败 |
|
可根据芯片平台按需补充或修改函数内容、参数及返回值 |
ty_pwm_stop
函数名 | ty_pwm_stop |
---|---|
uint32_t ty_pwm_stop(ty_pwm_t* p_pwm); | |
停止 PWM 输出 | |
p_pwm [in]:pwm 参数,由 ty_pwm_t 类型定义 | |
0 :成功;其他:失败 |
|
可根据芯片平台按需补充或修改函数内容、参数及返回值 |
ty_pwm_control
函数名 | ty_pwm_control |
---|---|
uint32_t ty_pwm_control(ty_pwm_t* p_pwm, uint8_t cmd, void* arg); | |
控制 PWM 模块 | |
p_pwm [inout]:pwm 参数,由 ty_pwm_t 类型定义cmd [in]:控制命令,由 ty_pwm_cmd_t 类型定义arg [in]:命令参数,取决于控制命令 | |
0 :成功;其他:失败 |
|
可根据芯片平台按需补充或修改函数内容、参数及返回值 |
ty_pwm_uninit
函数名 | ty_pwm_uninit |
---|---|
uint32_t ty_pwm_uninit(ty_pwm_t* p_pwm); | |
关闭 PWM 模块 | |
p_pwm [in]:pwm 参数,由 ty_pwm_t 类型定义 | |
0 :成功;其他:失败 |
|
可根据芯片平台按需补充或修改函数内容、参数及返回值 |
2.4 数据结构
ty_pwm_t
typedef struct {
GPIO_PinTypeDef pin; /* 引脚编号 */
pwm_id id; /* PWM ID */
uint8_t polarity; /* 极性 */
uint32_t freq; /* 周期 */
uint8_t duty; /* 占空比 */
} ty_pwm_t;
ty_pwm_cmd_t
typedef enum {
TY_PWM_CMD_SET_POLARITY = 0, /* 极性 */
TY_PWM_CMD_SET_FREQ, /* 周期 */
TY_PWM_CMD_SET_DUTY, /* 占空比 */
} ty_pwm_cmd_t;
ty_pwm_set_polarity_t
typedef struct {
uint8_t polarity; /* 极性(0-H, 1-L) */
} ty_pwm_set_polarity_t;
ty_pwm_set_freq_t
typedef struct {
uint32_t freq; /* 周期(us) */
} ty_pwm_set_freq_t;
ty_pwm_set_duty_t
typedef struct {
uint8_t duty; /* 占空比(%) */
} ty_pwm_set_duty_t;
2.5 API 示例
以 TLSR825x 平台为例,可参考以下代码补充 PWM 模块的 API 函数,或者直接在应用代码中调用芯片原厂提供的 API 来实现相关功能。
/* 根据TLSR825x的pwm通道和引脚对应关系,修改参数id为func */
typedef struct {
GPIO_PinTypeDef pin; /* 引脚编号 */
GPIO_FuncTypeDef func; /* 引脚功能 */
uint8_t polarity; /* 极性 */
uint32_t freq; /* 周期 */
uint8_t duty; /* 占空比 */
} ty_pwm_t;
/**************************************************** PWM0 : PA2. PC1. PC2. PD5. PWM1 : PA3. PC3. PWM2 : PA4. PC4. PWM3 : PB0. PD2. PWM4 : PB1. PB4. PWM5 : PB2. PB5. PWM0_N : PA0. PB3. PC4. PD5. PWM1_N : PC1. PD3. PWM2_N : PD4. PWM3_N : PC5. PWM4_N : PC0. PC6. PWM5_N : PC7. ****************************************************/
uint32_t ty_pwm_init(ty_pwm_t* p_pwm)
{
if (p_pwm == NULL) {
return 1;
}
if (p_pwm->duty < 0 || p_pwm->duty > 100) {
return 2;
}
if (p_pwm->func < AS_PWM0 || p_pwm->func > AS_PWM5_N) {
return 3;
}
pwm_set_clk(CLOCK_SYS_CLOCK_HZ, CLOCK_SYS_CLOCK_HZ);
gpio_set_func(p_pwm->pin, p_pwm->func);
pwm_id id = (p_pwm->func < AS_PWM0_N) ? (p_pwm->func - AS_PWM0) : (p_pwm->func - AS_PWM0_N);
pwm_set_mode(id, PWM_NORMAL_MODE);
pwm_polo_enable(id, p_pwm->polarity);
pwm_set_cycle_and_duty(id, (uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US),
(uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US * p_pwm->duty / 100));
return 0;
}
uint32_t ty_pwm_start(ty_pwm_t* p_pwm)
{
if (p_pwm == NULL) {
return 1;
}
if (p_pwm->duty < 0 || p_pwm->duty > 100) {
return 2;
}
if (p_pwm->func < AS_PWM0 || p_pwm->func > AS_PWM5_N) {
return 3;
}
pwm_id id = (p_pwm->func < AS_PWM0_N) ? (p_pwm->func - AS_PWM0) : (p_pwm->func - AS_PWM0_N);
pwm_start(id);
return 0;
}
uint32_t ty_pwm_stop(ty_pwm_t* p_pwm)
{
if (p_pwm == NULL) {
return 1;
}
if (p_pwm->func < AS_PWM0 || p_pwm->func > AS_PWM5_N) {
return 3;
}
pwm_id id = (p_pwm->func < AS_PWM0_N) ? (p_pwm->func - AS_PWM0) : (p_pwm->func - AS_PWM0_N);
pwm_stop(id);
return 0;
}
uint32_t ty_pwm_control(ty_pwm_t* p_pwm, uint8_t cmd, void* arg)
{
if ((p_pwm == NULL) || (arg == NULL)) {
return 1;
}
if (p_pwm->func < AS_PWM0 || p_pwm->func > AS_PWM5_N) {
return 3;
}
pwm_id id = (p_pwm->func < AS_PWM0_N) ? (p_pwm->func - AS_PWM0) : (p_pwm->func - AS_PWM0_N);
switch(cmd) {
case TY_PWM_CMD_SET_POLARITY: {
ty_pwm_set_polarity_t* param = arg;
p_pwm->polarity = param->polarity;
pwm_polo_enable(id, p_pwm->polarity);
}
break;
case TY_PWM_CMD_SET_FREQ: {
ty_pwm_set_freq_t* param = arg;
p_pwm->freq = param->freq;
pwm_set_cycle_and_duty(id, (uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US),
(uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US * p_pwm->duty / 100));
}
break;
case TY_PWM_CMD_SET_DUTY: {
ty_pwm_set_duty_t* param = arg;
if (p_pwm->duty < 0 || p_pwm->duty > 100) {
return 2;
}
p_pwm->duty = param->duty;
pwm_set_cmp(id, (uint16_t)(p_pwm->freq * CLOCK_SYS_CLOCK_1US * p_pwm->duty / 100));
}
break;
default:
break;
}
return 0;
}
uint32_t ty_pwm_uninit(ty_pwm_t* p_pwm)
{
uint32_t res = ty_pwm_stop(p_pwm);
if (res) {
return res;
}
gpio_set_func(p_pwm->pin, AS_GPIO);
return 0;
}