涂鸦蓝牙SDK开发系列教程——8.Board API 说明

本文详细介绍了涂鸦智能硬件开发中涉及的GPIO、PWM、ADC、I2C和Flash接口的API,包括初始化、控制、读写等操作,并提供了示例代码。这些接口覆盖了从基本的数字输入输出到模拟信号读取,再到I2C通信和存储器操作,为开发者提供了实现产品功能的基础。
摘要由CSDN通过智能技术生成

Board 层 API 是涂鸦抽象各芯片硬件外设,封装的一层标准接口。您可以调用这些 API 来使用相应外设,快速实现产品功能,也可以根据需要直接调用原厂外设接口。


Board 层功能模块列表如下:

名称API 文件功能说明
PINty_pin.hGPIO 外设相关函数的使用说明
PWMty_pwm.hPWM 外设相关函数的使用说明
ADCty_adc.hADC 外设相关函数的使用说明
I2Cty_i2c.hI2C 外设相关函数的使用说明
FLASHty_flash.hFlash 外设相关函数的使用说明

API Demo 获取:tuya_ble_board_api_demo


一. PIN

1.1 文件说明

API 文件

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

Demo 文件

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 来实现相关功能。

ty_pin.h

/* ! 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);

ty_pin_tlsr825x.c

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 文件说明

API 文件

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

Demo 文件

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 来实现相关功能。

ty_pwm.h

/* 根据TLSR825x的pwm通道和引脚对应关系,修改参数id为func */
typedef struct {
    GPIO_PinTypeDef pin;            /* 引脚编号 */
    GPIO_FuncTypeDef func;          /* 引脚功能 */
    uint8_t polarity;               /* 极性 */
    uint32_t freq;                  /* 周期 */
    uint8_t duty;                   /* 占空比 */
} ty_pwm_t;

ty_pwm_tlsr825x.c

/****************************************************
    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;
}

2.6 应用示例

功能概述

初期输出周期 500us,占空比 50%,极性高电平的 PWM 波形;2s 后,更新占空比为 80%;再 2s 后,更新周期为 800us;再 2s 后,更新极性为低电平;再 2s 后,停止 PWM 输出并关闭 PWM 模块。

代码示例

以 TLSR825x 平台为例:

#include "ty_pwm_demo.h"
#include "ty_pwm.h"
#include "tuya_ble_log.h"
#include "tuya_ble_port.h"

/***********************************************************
************************micro define************************
***********************************************************/
#define PWM_PIN             GPIO_PB5
#define PWM_FUNC            AS_PWM5

#define PWM_POL             0
#define PWM_POL_UPDATE      1
#define PWM_FREQ            500
#define PWM_FREQ_UPDATE     800
#define PWM_DUTY            50
#define PWM_DUTY_UPDATE     80

#define PWM_UPDATE_TIME_MS  2000

/***********************************************************
***********************variable define**********************
***********************************************************/
static ty_pwm_t sg_pwm = {
    .pin = PWM_PIN,
    .func = PWM_FUNC,
    .polarity = PWM_POL,
    .freq = PWM_FREQ,
    .duty = PWM_DUTY
};

static tuya_ble_timer_t sg_pwm_timer;

/***********************************************************
***********************function define**********************
***********************************************************/
/**
 * @brief pwm timer callback
 * @param[in] none
 * @return none
 */
void __pwm_timer_cb(void)
{
    static uint8_t s_step = 0;

    switch (s_step) {
    case 0: {
            ty_pwm_set_duty_t new_duty = {
                .duty = PWM_DUTY_UPDATE
            };
            ty_pwm_control(&sg_pwm, TY_PWM_CMD_SET_DUTY, &new_duty);
        }
        break;
    case 1: {
            ty_pwm_set_freq_t new_freq = {
                .freq = PWM_FREQ_UPDATE
            };
            ty_pwm_control(&sg_pwm, TY_PWM_CMD_SET_FREQ, &new_freq);
        }
        break;
    case 2: {
            ty_pwm_set_polarity_t new_pol = {
                .polarity = PWM_POL_UPDATE
            };
            ty_pwm_control(&sg_pwm, TY_PWM_CMD_SET_POLARITY, &new_pol);
        }
        break;
    case 3: {
            ty_pwm_stop(&sg_pwm);
            ty_pwm_uninit(&sg_pwm);
        }
        break;
    default:
        break;
    }
    if (s_step <= 3) {
        s_step++;
    }
}

/**
 * @brief ty_pwm api demo init
 * @param none
 * @return none
 */
void ty_pwm_demo_init(void)
{
    uint32_t res;
    res = ty_pwm_init(&sg_pwm);
    if (res) {
        TUYA_APP_LOG_ERROR("ty_pwm_init failed, error code: %d", res);
        return;
    }
    res = ty_pwm_start(&sg_pwm);
    if (res) {
        TUYA_APP_LOG_ERROR("ty_pwm_start failed, error code: %d", res);
        return;
    }
    tuya_ble_timer_create(&sg_pwm_timer, PWM_UPDATE_TIME_MS, TUYA_BLE_TIMER_REPEATED, (tuya_ble_timer_handler_t)__pwm_timer_cb);
    tuya_ble_timer_start(sg_pwm_timer);
}


三. ADC

3.1 文件说明

API 文件

ADC 相关 API 位于 ty_adc.h 文件中,芯片平台关联的驱动代码位于 ty_adc_xxxx.c 文件中。

tuya_ble_sdk_demo
└── board
     ├── include
     |    └── ty_adc.h
     ├── xxxx                      /* xxxx 为芯片平台,如 TLSR825x */
     |    └── ty_board_xxxx        /* xxxx 为芯片平台,如 ty_board_tlsr825x */
     |         └── ty_adc_xxxx.c   /* xxxx 为芯片平台,如 ty_adc_tlsr825x.c */
     └── board.h

Demo 文件

tuya_board_api_demo 的 ADC Demo 文件结构如下:

tuya_ble_sdk_demo
├── app  /* API 应用示例 */
|    ├── include
|    |    └── ty_board_demo
|    |    |    ├── demo_config.h        /* demo 配置文件 */
|    |    |    └── ty_adc_demo.h        /* adc 模块示例代码 */
|    |    ├── tuya_ble_board_api_demo.h /* board api 示例程序入口 */
|    |    └── tuya_ble_sdk_demo.h       /* tuya_ble_sdk 应用入口 */
|    └── src
|         ├── ty_board_demo
|         |    └── ty_adc_demo.c        /* adc 模块示例代码 */
|         ├── tuya_ble_board_api_demo.c /* board api 示例程序入口 */
|         └── tuya_ble_sdk_demo.c       /* tuya_ble_sdk 应用入口 */
└── board /* 部分 API 修改示例 */

修改 demo_config.h 文件即可切换到 ADC 模块示例程序:

#define BOARD_API_DEMO          BOARD_API_ADC

3.2 API 列表

函数名称功能描述
ty_adc_init初始化 ADC 模块
ty_adc_start启动 ADC 采样
ty_adc_stop停止 ADC 采样
ty_adc_control控制 ADC 模块
ty_adc_uninit关闭 ADC 模块

3.3 API 说明

ty_adc_init

函数名ty_adc_init
函数原型uint32_t ty_adc_init(ty_adc_t* p_adc);
功能概述初始化 ADC 模块
参数p_adc [in]:adc 参数,由 ty_adc_t 类型定义
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_adc_start

函数名ty_adc_start
函数原型uint32_t ty_adc_start(ty_adc_t* p_adc);
功能概述启动 ADC 采样
参数p_adc [inout]:adc 参数,由 ty_adc_t 类型定义
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_adc_stop

函数名ty_adc_stop
函数原型uint32_t ty_adc_stop(ty_adc_t* p_adc);
功能概述停止 ADC 采样
参数p_adc [in]:adc 参数,由 ty_adc_t 类型定义
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_adc_control

函数名ty_adc_control
函数原型uint32_t ty_adc_control(ty_adc_t* p_adc, uint8_t cmd, void* arg);
功能概述控制 ADC 模块
参数p_adc [in]:adc 参数,由 ty_adc_t 类型定义
cmd [in]:控制命令
arg [in]:命令参数
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_adc_uninit

函数名ty_adc_uninit
函数原型uint32_t ty_adc_uninit(ty_adc_t* p_adc);
功能概述关闭 ADC 模块
参数p_adc [in]:adc 参数,由 ty_adc_t 类型定义
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

3.4 数据结构

ty_adc_t

/* TLSR825x 平台 */
typedef struct {
    GPIO_PinTypeDef pin;        /* 引脚编号 */
    ADC_InputPchTypeDef channel;/* ADC 通道 */
    uint32_t value;             /* ADC 采样结果 */
} ty_adc_t;

/* nRF52832 平台 */
typedef struct {
    uint8_t channel;            /* ADC 通道 */
    int16_t value;              /* ADC 采样结果 */
} ty_adc_t;

3.5 API 示例

以 TLSR825x 平台为例,可参考以下代码补充 ADC 模块的 API 函数,或者直接在应用代码中调用芯片原厂提供的 API 来实现相关功能。

ty_adc.h

/* ! 本示例中channel成员可删除 */
typedef struct {
    GPIO_PinTypeDef pin;        /* 引脚编号 */
    uint32_t value;             /* ADC 采样结果 */
} ty_adc_t;

ty_adc_tlsr825x.c

uint32_t ty_adc_init(ty_adc_t* p_adc)
{
    adc_init();
    adc_base_init(p_adc->pin);
    adc_power_on_sar_adc(1);
}

uint32_t ty_adc_start(ty_adc_t* p_adc)
{
    p_adc.value = adc_sample_and_get_result();
    return 0;
}

3.6 应用示例

功能概述

采集 ADC 引脚的电压值,每秒读取 1 次。

代码示例

以 TLSR825x 平台为例:

#include "ty_adc_demo.h"
#include "ty_adc.h"
#include "tuya_ble_log.h"
#include "tuya_ble_port.h"

/***********************************************************
************************micro define************************
***********************************************************/
#define ADC_PIN             GPIO_PB6
#define ADC_SAMPLE_TIME_MS  1000

/***********************************************************
***********************variable define**********************
***********************************************************/
static ty_adc_t sg_adc = {
    .pin = ADC_PIN,
    .value = 0
};

static tuya_ble_timer_t sg_adc_timer;

/***********************************************************
***********************function define**********************
***********************************************************/
/**
 * @brief adc timer callback
 * @param none
 * @return none
 */
void __adc_timer_cb(void)
{
    uint32_t res = ty_adc_start(&sg_adc);
    if (res) {
        TUYA_APP_LOG_ERROR("ty_adc_start failed, error code: %d", res);
    } else {
        TUYA_APP_LOG_INFO("adc_value is: %d mV", sg_adc.value);
    }
}

/**
 * @brief ty_adc api demo init
 * @param none
 * @return none
 */
void ty_adc_demo_init(void)
{
    uint32_t res = ty_adc_init(&sg_adc);
    if (res) {
        TUYA_APP_LOG_ERROR("ty_adc_init failed, error code: %d", res);
        return;
    }
    tuya_ble_timer_create(&sg_adc_timer, ADC_SAMPLE_TIME_MS, TUYA_BLE_TIMER_REPEATED, (tuya_ble_timer_handler_t)__adc_timer_cb);
    tuya_ble_timer_start(sg_adc_timer);
}


四. I2C

4.1 文件说明

API 文件

I2C 相关 API 位于 ty_i2c.h 文件中,芯片平台关联的驱动代码位于 ty_i2c_xxxx.c 文件中。

tuya_ble_sdk_demo
└── board
     ├── include
     |    └── ty_i2c.h
     ├── xxxx                      /* xxxx 为芯片平台,如 TLSR825x */
     |    └── ty_board_xxxx        /* xxxx 为芯片平台,如 ty_board_tlsr825x */
     |         └── ty_i2c_xxxx.c   /* xxxx 为芯片平台,如 ty_i2c_tlsr825x.c */
     └── board.h

Demo 文件

tuya_board_api_demo 的 I2C Demo 文件结构如下:

tuya_ble_sdk_demo
├── app  /* API 应用示例 */
|    ├── include
|    |    └── ty_board_demo
|    |    |    ├── demo_config.h        /* demo 配置文件 */
|    |    |    └── ty_i2c_demo.h        /* i2c 模块示例代码 */
|    |    ├── tuya_ble_board_api_demo.h /* board api 示例程序入口 */
|    |    └── tuya_ble_sdk_demo.h       /* tuya_ble_sdk 应用入口 */
|    └── src
|         ├── ty_board_demo
|         |    └── ty_i2c_demo.c        /* i2c 模块示例代码 */
|         ├── tuya_ble_board_api_demo.c /* board api 示例程序入口 */
|         └── tuya_ble_sdk_demo.c       /* tuya_ble_sdk 应用入口 */
└── board /* 部分 API 修改示例 */

修改 demo_config.h 文件即可切换到 I2C 模块示例程序:

#define BOARD_API_DEMO          BOARD_API_I2C

4.2 API 列表

函数名称功能描述
ty_i2c_init初始化 I2C 模块
ty_i2c_start硬件 I2C:启动 I2C 传输
ty_i2c_stop硬件 I2C:停止 I2C 传输
ty_i2c_control硬件I2C:控制 I2C 模块
ty_i2c_uninit硬件 I2C:关闭 I2C 模块
ty_i2c_send硬件 I2C:发送数据
i2c_send_bytes软件 I2C:发送多个字节数据
i2c_rcv_bytes软件 I2C:接收多个字节数据
i2c_soft_cfg软件 I2C:配置从机寄存器
i2c_soft_gpio_init软件 I2C:初始 I2C 引脚
i2c_start软件 I2C:发送起始信号
i2c_stop软件 I2C:发送停止信号
i2c_delay软件 I2C:微秒级延时

4.3 API 说明

ty_i2c_init

函数名ty_i2c_init
函数原型uint32_t ty_i2c_init(void);
功能概述初始化 I2C 模块
参数
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_i2c_start

函数名ty_i2c_start
函数原型uint32_t ty_i2c_start(void);
功能概述硬件 I2C:启动 I2C 传输
参数
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_i2c_stop

函数名ty_i2c_stop
函数原型uint32_t ty_i2c_stop(void);
功能概述硬件 I2C:停止 I2C 传输
参数
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_i2c_control

函数名ty_i2c_control
函数原型uint32_t ty_i2c_control(uint8_t cmd, void* arg);
功能概述硬件I2C:控制 I2C 模块
参数cmd [in]:控制命令
arg [in]:命令参数
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_i2c_uninit

函数名ty_i2c_uninit
函数原型uint32_t ty_i2c_uninit(void);
功能概述硬件 I2C:关闭 I2C 模块
参数
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_i2c_send

函数名ty_i2c_send
函数原型uint32_t ty_i2c_send(const uint8_t addr, const uint8_t* buf, uint32_t size);
功能概述硬件 I2C:发送数据
参数addr [in]:地址
buf [in]:发送数据
size [in]:数据大小
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

i2c_send_bytes

函数名i2c_send_bytes
函数原型void i2c_send_bytes(uint8_t adderss_cmd, uint8_t *buff, uint8_t len);
功能概述软件 I2C:发送多个字节数据
参数adderss_cmd [in]:“从机地址+读写命令”字节
buff [in]:发送数据
len [in]:数据长度
返回值
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

i2c_rcv_bytes

函数名i2c_rcv_bytes
函数原型void i2c_rcv_bytes(uint8_t adderss_cmd, uint8_t *buff, uint8_t len);
功能概述软件 I2C:接收多个字节数据
参数adderss_cmd [in]:“从机地址+读写命令”字节
buff [out]:接收数据
len [in]:数据长度
返回值
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

i2c_soft_cfg

函数名i2c_soft_cfg
函数原型void i2c_soft_cfg(uint8_t adderss_cmd, uint8_t reg_addr, uint8_t data);
功能概述软件 I2C:配置从机寄存器
参数adderss_cmd [in]:“从机地址+读写命令”字节
reg_addr [in]:寄存器地址
data [in]:寄存器值
返回值
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

i2c_soft_gpio_init

函数名i2c_soft_gpio_init
函数原型void i2c_soft_gpio_init(void);
功能概述软件 I2C:初始 I2C 引脚
参数
返回值
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

i2c_start

函数名i2c_start
函数原型void i2c_start(void);
功能概述软件 I2C:发送起始信号
参数
返回值
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

i2c_stop

函数名i2c_stop
函数原型void i2c_stop(void);
功能概述软件 I2C:发送停止信号
参数
返回值
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

i2c_delay

函数名i2c_delay
函数原型void i2c_delay(unsigned long tim_1us);
功能概述软件 I2C:微秒级延时
参数tim_1us[in]:微秒值
返回值
备注

4.4 数据结构

无。


4.5 API 示例

以 TLSR825x 平台为例,可参考以下代码补充 I2C 模块的 API 函数,或者直接在应用代码中调用芯片原厂提供的 API 来实现相关功能。

ty_i2c.h

/* !该宏用于区分使用软件I2C还是硬件I2C;本Demo已将软/硬件I2C接口函数专用化,因此该宏可忽略 */
#define  USE_SOFT_I2C            0

/* !修改了addr的类型,增加了addr_len参数,增加了ty_i2c_rcv函数 */
uint32_t ty_i2c_send(const uint32_t addr, const uint8_t addr_len, const uint8_t* buf, uint32_t size);
uint32_t ty_i2c_rcv(const uint32_t addr, const uint8_t addr_len, uint8_t* buf, uint32_t size);

ty_i2c_tlsr825x.c

/* !I2C的引脚在这里配置,增加了SLAVE_ADDR_WRITE用于硬件I2C初始化 */
#define TLSR_I2C_GPIO_GROUP     I2C_GPIO_GROUP_C0C1
#define I2C_PIN_SDA             GPIO_PC0
#define I2C_PIN_SCL             GPIO_PC1
#define SLAVE_ADDR_WRITE        (0x44 << 1 | 0x00)  // (0x68 << 1 | 0x00)

/* !修改了i2c_master_init的传入参数 */
uint32_t ty_i2c_init(void)
{
    i2c_gpio_set(TLSR_I2C_GPIO_GROUP);
    i2c_master_init(SLAVE_ADDR_WRITE, (unsigned char)(CLOCK_SYS_CLOCK_HZ/(4*200000)));
    return 0;
}

/* !修改了发送函数的参数和内容,这里addr表示寄存器地址,addr_len表示地址所占字节个数 */
uint32_t ty_i2c_send(const uint32_t addr, const uint8_t addr_len, const uint8_t* buf, uint32_t size)
{
     i2c_write_series(addr, addr_len, buf, size);
     return 0;
}

/* !增加了接收函数,参数含义与发送函数相同 */
uint32_t ty_i2c_rcv(const uint32_t addr, const uint8_t addr_len, uint8_t* buf, uint32_t size)
{
     i2c_read_series(addr, addr_len, buf, size);
     return 0;
}

4.6 应用示例

功能概述

使用硬件 I2C 或 软件 I2C 驱动从机设备,定时采集传感器数据。

代码示例

以 TLSR825x 平台为例。

I2C_API_DEMO_SHT3X - 温湿度传感器 SHT30-DIS 驱动示例

传感资料:

注:SHT3x 的 16 位命令可以作为寄存器地址使用。

#include "ty_i2c_demo.h"
#include "ty_i2c.h"
#include "tuya_ble_log.h"
#include "tuya_ble_port.h"

/***********************************************************
************************micro define************************
***********************************************************/
/* Demo config */
#define I2C_API_DEMO_S              0x00            /* software I2C */
#define I2C_API_DEMO_H              0x01            /* hardware I2C */
#define I2C_API_DEMO_MODE           I2C_API_DEMO_S

/* slave device config */
#define I2C_SLAVE_ADDR              0x44
#define I2C_DAQ_TIME_MS             1000            /* 1s / 1Hz */
/* register map */
#define SHT3X_CMD_MEAS_PERI_1_H     0x2130          /* measurement: periodic 1 mps, high repeatability */
#define SHT3X_CMD_FETCH_DATA        0xE000          /* readout measurements for periodic mode */

/* I2C command */
#define I2C_CMD_BIT_WRITE           0
#define I2C_CMD_BIT_READ            1
#define I2C_ADDR_CMD_W              (I2C_SLAVE_ADDR << 1 | I2C_CMD_BIT_WRITE)
#define I2C_ADDR_CMD_R              (I2C_SLAVE_ADDR << 1 | I2C_CMD_BIT_READ)

/***********************************************************
***********************variable define**********************
***********************************************************/
static tuya_ble_timer_t sg_daq_timer;

/***********************************************************
***********************function define**********************
***********************************************************/
/**
 * @brief check checksum
 * @param[in] data: data to be checked
 * @param[in] len: data length
 * @param[in] crc_val: crc value
 * @return check result
 */
static uint8_t __check_crc_8(uint8_t* data, uint16_t len, uint8_t crc_val)
{
    uint8_t i;
    uint8_t crc = 0xFF;

    while (len--) {
        crc ^= *data;
        for (i = 8; i > 0; --i) {
            if (crc & 0x80) {
                crc = (crc << 1) ^ 0x31;
            } else {
                crc = (crc << 1);
            }
        }
        data++;
    }

    if (crc != crc_val){
        return 0;
    }
    return 1;
}

/**
 * @brief write command to SHT3x
 * @param[in] cmd: command
 * @param[in] stop: whether a stop signal needs to be sent
 * @return none
 */
static void __i2c_write_cmd_sht3x(uint16_t cmd, bool stop)
{
#if (I2C_API_DEMO_MODE == I2C_API_DEMO_S)
    uint8_t cmd_bytes[2];
    cmd_bytes[0] = (uint8_t)(cmd >> 8);
    cmd_bytes[1] = (uint8_t)(cmd & 0x00FF);
    i2c_start();
    i2c_send_bytes(I2C_ADDR_CMD_W, cmd_bytes, 2);
    if (stop) {
        i2c_stop();
    }
#else
    ty_i2c_send(cmd, 2, null, 0);
#endif
}

/**
 * @brief read data from SHT3x
 * @param[out] buf: data buffer
 * @param[in] len: data length
 * @return none
 */
static void __i2c_read_data_sht3x(uint8_t *buf, uint8_t len)
{
#if (I2C_API_DEMO_MODE == I2C_API_DEMO_S)
    i2c_start();
    i2c_rcv_bytes(I2C_ADDR_CMD_R, buf, len);
    i2c_stop();
#else
    ty_i2c_rcv(0, 0, buf, len);
#endif
}

/**
 * @brief data acquisition timer handler
 * @param none
 * @return none
 */
static void __daq_timer_handler(void)
{
    uint8_t buf[6];
    /* send fetch command to SHT3x */
    __i2c_write_cmd_sht3x(SHT3X_CMD_FETCH_DATA, 0);
    /* read data from SHT3x */
    __i2c_read_data_sht3x(buf, 6);
    /* check CRC value */
    if ((!__check_crc_8(buf, 2, buf[2])) ||
        (!__check_crc_8(buf+3, 2, buf[5]))) {
        TUYA_APP_LOG_ERROR("__sht3x_check_crc failed.");
        return;
    }
    /* calculate temperature and humidity */
    int32_t temp = ((int16_t)buf[0] << 8 | buf[1]) * 175 / 65535 - 45;
    uint32_t humi = ((uint16_t)buf[3] << 8 | buf[4]) * 100 / 65535;
    TUYA_APP_LOG_INFO("Temperature: %d, Humidity: %d", temp, humi);
}

/**
 * @brief ty_i2c api demo init
 * @param none
 * @return none
 */
void ty_i2c_demo_init(void)
{
    /* I2C init */
#if (I2C_API_DEMO_MODE == I2C_API_DEMO_S)
    i2c_soft_gpio_init();
#else
    ty_i2c_init();
#endif
    /* SHT3x: start periodic measurement */
    __i2c_write_cmd_sht3x(SHT3X_CMD_MEAS_PERI_1_H, 0);
    /* creat and start DAQ timer */
    tuya_ble_timer_create(&sg_daq_timer, I2C_DAQ_TIME_MS, TUYA_BLE_TIMER_REPEATED, (tuya_ble_timer_handler_t)__daq_timer_handler);
    tuya_ble_timer_start(sg_daq_timer);
}

I2C_API_DEMO_MPU6050 - 运动传感器 MPU6050 驱动示例

传感资料:

#include "ty_i2c_demo.h"
#include "ty_i2c.h"
#include "tuya_ble_log.h"
#include "tuya_ble_port.h"

/***********************************************************
************************micro define************************
***********************************************************/
/* Demo config */
#define I2C_API_DEMO_S              0x00            /* software I2C */
#define I2C_API_DEMO_H              0x01            /* hardware I2C */
#define I2C_API_DEMO_MODE           I2C_API_DEMO_S

/* slave device config */
#define I2C_SLAVE_ADDR              0x68
#define I2C_DAQ_TIME_MS             5               /* 5ms / 200Hz */
#define MPU6050_DEV_ID              0x68
/* register map */
#define MPU6050_RA_SMPRT_DIV        0x19
#define MPU6050_RA_CONFIG           0x1A
#define MPU6050_RA_GYRO_CONFIG      0x1B
#define MPU6050_RA_ACCEL_CONFIG     0x1C
#define MPU6050_RA_ACCEL_XOUT_H     0x3B
#define MPU6050_RA_PWR_MGMT_1       0x6B
#define MPU6050_RA_WHO_AM_I         0x75

/* I2C command */
#define I2C_CMD_BIT_WRITE           0
#define I2C_CMD_BIT_READ            1
#define I2C_ADDR_CMD_W              (I2C_SLAVE_ADDR << 1 | I2C_CMD_BIT_WRITE)
#define I2C_ADDR_CMD_R              (I2C_SLAVE_ADDR << 1 | I2C_CMD_BIT_READ)

/***********************************************************
***********************variable define**********************
***********************************************************/
static tuya_ble_timer_t sg_daq_timer;

/***********************************************************
***********************function define**********************
***********************************************************/
/**
 * @brief write register of MPU6050
 * @param[in] reg_addr: register address
 * @param[in] reg_val: value to be written
 * @return none
 */
static void __i2c_write_reg(uint8_t reg_addr, uint8_t reg_val)
{
#if (I2C_API_DEMO_MODE == I2C_API_DEMO_S)
    i2c_soft_cfg(I2C_ADDR_CMD_W, reg_addr, reg_val);
#else
    ty_i2c_send(reg_addr, 1, &reg_val, 1);
#endif
}

/**
 * @brief read register of MPU6050
 * @param[in] reg_addr: register address
 * @param[out] reg_val: register value
 * @param[in] len: register length
 * @return none
 */
static void __i2c_read_reg(uint8_t reg_addr, uint8_t *reg_val, uint8_t len)
{
#if (I2C_API_DEMO_MODE == I2C_API_DEMO_S)
    i2c_start();
    i2c_send_bytes(I2C_ADDR_CMD_W, &reg_addr, 1);
    i2c_start();
    i2c_rcv_bytes(I2C_ADDR_CMD_R, reg_val, len);
    i2c_stop();
#else
    ty_i2c_rcv(reg_addr, 1, reg_val, len);
#endif
}

/**
 * @brief data acquisition timer handler
 * @param none
 * @return none
 */
static void __daq_timer_handler(void)
{
    uint8_t i;
    uint8_t tmp_buf[14];
    int16_t accel[3], gyro[3];
    /* read data from MPU6050 */
    __i2c_read_reg(MPU6050_RA_ACCEL_XOUT_H, tmp_buf, 14);
    /* calculate acceleration (g) and angular velocity (dps) */
    for (i = 0; i < 3; i++) {
        accel[i] = ((int16_t)tmp_buf[i*2] << 8) | tmp_buf[i*2+1];
        accel[i] /= 2048;
        gyro[i] = ((int16_t)tmp_buf[i*2+8] << 8) | tmp_buf[i*2+9];
        gyro[i] = gyro[i] * 10 / 164;
    }
    TUYA_APP_LOG_INFO("ax: %d,   ay: %d,   az: %d,   gx: %d,  gy: %d,  gz: %d",
                       accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
}

/**
 * @brief ty_i2c api demo init
 * @param none
 * @return none
 */
void ty_i2c_demo_init(void)
{
    /* I2C init */
#if (I2C_API_DEMO_MODE == I2C_API_DEMO_S)
    i2c_soft_gpio_init();
#else
    ty_i2c_init();
#endif
    /* reset MPU6050 and exit sleep mode */
    __i2c_write_reg(MPU6050_RA_PWR_MGMT_1, 0x80);
    i2c_delay(200*1000);
    /* check communication */
    uint8_t dev_id;
    __i2c_read_reg(MPU6050_RA_WHO_AM_I, &dev_id, 1);
    if (dev_id != MPU6050_DEV_ID) {
        TUYA_APP_LOG_ERROR("MPU6050 is not found.");
        return;
    }
    /* MPU6050 init */
    __i2c_write_reg(MPU6050_RA_PWR_MGMT_1, 0x01);   /* set clock source: PLL_XGYRO */
    __i2c_write_reg(MPU6050_RA_GYRO_CONFIG, 0x03);  /* set gyroscope's full-scale range: 2000dps */
    __i2c_write_reg(MPU6050_RA_ACCEL_CONFIG, 0x03); /* set accelerometer's full-scale range: 16g */
    __i2c_write_reg(MPU6050_RA_SMPRT_DIV, 0x04);    /* set sample rate: 1kHz/(1+4) = 200Hz */
    __i2c_write_reg(MPU6050_RA_CONFIG, 0x02);       /* set DLPF */

    /* creat and start DAQ timer */
    tuya_ble_timer_create(&sg_daq_timer, I2C_DAQ_TIME_MS, TUYA_BLE_TIMER_REPEATED, (tuya_ble_timer_handler_t)__daq_timer_handler);
    tuya_ble_timer_start(sg_daq_timer);
}


五. FLASH

5.1 文件说明

API 文件

Flash 相关 API 位于 ty_flash.h 文件中,芯片平台关联的驱动代码位于 ty_flash_xxxx.c 文件中。

tuya_ble_sdk_demo
└── board
     ├── include
     |    └── ty_flash.h
     ├── xxxx                      /* xxxx 为芯片平台,如 TLSR825x */
     |    └── ty_board_xxxx        /* xxxx 为芯片平台,如 ty_board_tlsr825x */
     |         └── ty_flash_xxxx.c /* xxxx 为芯片平台,如 ty_flash_tlsr825x.c */
     └── board.h

Demo 文件

tuya_board_api_demo 的 Flash Demo 文件结构如下:

tuya_ble_sdk_demo
├── app  /* API 应用示例 */
|    ├── include
|    |    └── ty_board_demo
|    |    |    ├── demo_config.h        /* demo 配置文件 */
|    |    |    └── ty_flash_demo.h      /* flash 模块示例代码 */
|    |    ├── tuya_ble_board_api_demo.h /* board api 示例程序入口 */
|    |    └── tuya_ble_sdk_demo.h       /* tuya_ble_sdk 应用入口 */
|    └── src
|         ├── ty_board_demo
|         |    └── ty_flash_demo.c      /* flash 模块示例代码 */
|         ├── tuya_ble_board_api_demo.c /* board api 示例程序入口 */
|         └── tuya_ble_sdk_demo.c       /* tuya_ble_sdk 应用入口 */
└── board /* 部分 API 修改示例 */

修改 demo_config.h 文件即可切换到 Flash 模块示例程序:

#define BOARD_API_DEMO          BOARD_API_FLASH

5.2 API 列表

函数名称功能描述
ty_flash_init初始化 Flash 模块
ty_flash_read读取 Flash
ty_flash_write写入 Flash
ty_flash_erase擦除 Flash

5.3 API 说明

ty_flash_init

函数名ty_flash_init
函数原型uint32_t ty_flash_init(void);
功能概述初始化 Flash 模块
参数
返回值0:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_flash_read

函数名ty_flash_read
函数原型uint32_t ty_flash_read(uint32_t addr, uint8_t* buf, uint32_t size);
功能概述读取 Flash
参数addr [in]:起始地址
buf [out]:Flash 数据
size [in]:数据大小
返回值TUYA_BLE_SUCCESS:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_flash_write

函数名ty_flash_write
函数原型uint32_t ty_flash_write(uint32_t addr, const uint8_t* buf, uint32_t size);
功能概述写入 Flash
参数addr [in]:起始地址
buf [in]:Flash 数据
size [in]:数据大小
返回值TUYA_BLE_SUCCESS:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值

ty_flash_erase

函数名ty_flash_erase
函数原型uint32_t ty_flash_erase(uint32_t addr, uint32_t num);
功能概述擦除 Flash
参数addr [in]:起始地址
num [in]:擦除单位的个数
返回值TUYA_BLE_SUCCESS:成功;其他:失败
备注可根据芯片平台按需补充或修改函数内容、参数及返回值,不同芯片平台的擦除单位可能不同

5.4 数据结构

无。


5.5 API 示例

无。可直接使用 SDK 中的 API 函数。


5.6 应用示例

功能概述

上电后读取 Flash 并打印,如果已写入过数据,擦除 Flash 后将新数据写入 Flash,擦除和写入操作后读一次数据用来检查操作是否成功。

代码示例

以 TLSR825x 平台为例:(Flash 地址可查看 tuya_ble_sdk_demo\doc 目录下的 flash 分区表)

#include "ty_flash_demo.h"
#include "ty_flash.h"
#include "tuya_ble_log.h"

/***********************************************************
************************micro define************************
***********************************************************/
#define FLASH_ADDR_STA      0x034000
#define FLASH_BUF_SIZE      4

/***********************************************************
***********************function define**********************
***********************************************************/
/**
 * @brief ty_flash api demo init
 * @param none
 * @return none
 */
void ty_flash_demo_init(void)
{
    uint8_t i;
    uint8_t flash_buf[FLASH_BUF_SIZE];
    uint8_t flash_buf_tmp[FLASH_BUF_SIZE];

    /* read flash */
    ty_flash_read(FLASH_ADDR_STA, flash_buf, FLASH_BUF_SIZE);
    for (i = 0; i < FLASH_BUF_SIZE; i++) {
        TUYA_APP_LOG_INFO("The data in %x is %02x", FLASH_ADDR_STA + 8*i, flash_buf[i]);
    }
    /* erase flash and check it */
    if (flash_buf[0] != 0xFF) {
        ty_flash_erase(FLASH_ADDR_STA, 1);
        ty_flash_read(FLASH_ADDR_STA, flash_buf_tmp, FLASH_BUF_SIZE);
        for (i = 0; i < FLASH_BUF_SIZE; i++) {
            TUYA_APP_LOG_INFO("The data in %x is %02x", FLASH_ADDR_STA + 8*i, flash_buf_tmp[i]);
        }
    }

    /* write flash and check it */
    for (i = 0; i < FLASH_BUF_SIZE; i++) {
        flash_buf[i] += (i+1);
    }
    ty_flash_write(FLASH_ADDR_STA, flash_buf, FLASH_BUF_SIZE);
    ty_flash_read(FLASH_ADDR_STA, flash_buf_tmp, FLASH_BUF_SIZE);
    for (i = 0; i < FLASH_BUF_SIZE; i++) {
        TUYA_APP_LOG_INFO("The data in %x is %02x", FLASH_ADDR_STA + 8*i, flash_buf_tmp[i]);
    }
}


上一篇: 第 7 课:SDK API 说明
下一篇:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值