TuyaOS
驱动框架

DRIVER

typedef enum {
TUYA_DRV_UART,
TUYA_DRV_PWM,
TUYA_DRV_TIMER,
TUYA_DRV_ADC,
TUYA_DRV_I2C,
} tuya_drv_type_t;

驱动查找

void *tuya_driver_find(uint8_t type, uint8_t port);
参数 描述
type tuya_drv_type_t 枚举中的值
port 端口号,例如TUYA_UART0,TUYA_UART1
返回 ——
!= NULL 查找成功,返回其对应的句柄
== NULL 查找失败

PIN

PIN接口列表

函数名称 功能描述
int tuya_pin_init(tuya_pin_name_t pin, tuya_pin_mode_t mode); 初始化引脚模式
int tuya_pin_write(tuya_pin_name_t pin, tuya_pin_level_t level); 设置引脚的电平
int tuya_pin_read(tuya_pin_name_t pin); 读取引脚的电平
int tuya_pin_irq_init(tuya_pin_name_t pin, tuya_pin_mode_t irq_mode, tuya_pin_irq_cb cb, void *arg); 初始化引脚中断
int tuya_pin_irq_enable(tuya_pin_name_t pin); 使能引脚中断
int tuya_pin_irq_disable(tuya_pin_name_t pin); 禁能引脚中断
int tuya_pin_control(tuya_pin_name_t pin, uint8_t cmd, void *arg); 引脚相关控制

PIN 访问名字

typedef enum {
TUYA_PINS_NAME(TUYA_PA),
TUYA_PINS_NAME(TUYA_PB),
TUYA_PINS_NAME(TUYA_PC),
TUYA_PINS_NAME(TUYA_PD),
TUYA_PINS_NAME(TUYA_PE),
} tuya_pin_name_t;

PIN 工作模式

typedef enum {
TUYA_PIN_MODE_IN_PU,
TUYA_PIN_MODE_IN_PD,
TUYA_PIN_MODE_IN_FL,
TUYA_PIN_MODE_IN_IRQ_RISE,
TUYA_PIN_MODE_IN_IRQ_FALL,
TUYA_PIN_MODE_IN_IRQ_RISE_FALL,
TUYA_PIN_MODE_IN_IRQ_LOW,
TUYA_PIN_MODE_IN_IRQ_HIGH,
TUYA_PIN_MODE_OUT_PP_LOW,
TUYA_PIN_MODE_OUT_PP_HIGH,
TUYA_PIN_MODE_OUT_PP_PU_LOW,
TUYA_PIN_MODE_OUT_PP_PU_HIGH,
TUYA_PIN_MODE_OUT_PP_PD_LOW,
TUYA_PIN_MODE_OUT_PP_PD_HIGH,
TUYA_PIN_MODE_OUT_OD_LOW,
TUYA_PIN_MODE_OUT_OD_HIZ,
TUYA_PIN_MODE_OUT_OD_PU_LOW,
TUYA_PIN_MODE_OUT_OD_PU_HIGH,
} tuya_pin_mode_t;

PIN 电平状态

typedef enum {
TUYA_PIN_LOW = 0,
TUYA_PIN_HIGH
} tuya_pin_level_t;

PIN接口描述

初始化引脚模式
int tuya_pin_init(tuya_pin_name_t pin, tuya_pin_mode_t mode);
参数 描述
pin tuya_pin_name_t枚举中的值
mode tuya_pin_mode_t枚举中的值
返回 ——
OPRT_OK 初始化成功
其他错误码 执行失败
设置引脚电平
int tuya_pin_write(tuya_pin_name_t pin, tuya_pin_level_t level);
参数 描述
pin tuya_pin_name_t枚举中的值
level tuya_pin_level_t枚举中的值
返回 ——
OPRT_OK 初始化成功
其他错误码 执行失败
读取引脚电平
int tuya_pin_read(tuya_pin_name_t pin)
参数 描述
pin tuya_pin_name_t枚举中的值
返回 ——
TUYA_PIN_LOW 低电平
TUYA_PIN_HIGH 高电平
初始化引脚中断模式
int tuya_pin_irq_init(tuya_pin_name_t pin, tuya_pin_mode_t irq_mode, tuya_pin_irq_cb cb, void *arg);
参数 描述
pin tuya_pin_name_t枚举中的值
irq_mode tuya_pin_mode_t枚举中的值
cb 注册的回调函数,参见如下函数原形
arg 注册的参数
返回 ——
OPRT_OK 初始化成功
其他错误码 执行失败

注册函数tuya_pin_irq_cb原形

typedef void (*tuya_pin_irq_cb)(void *args);
使能引脚中断
int tuya_pin_irq_enable(tuya_pin_name_t pin);
参数 描述
pin tuya_pin_name_t枚举中的值
返回 ——
OPRT_OK 初始化成功
其他错误码 执行失败
禁能引脚中断
int tuya_pin_irq_disable(tuya_pin_name_t pin);
参数 描述
pin tuya_pin_name_t枚举中的值
返回 ——
OPRT_OK 初始化成功
其他错误码 执行失败

PIN使用示例

void tuya_pa5_irq_cb(void *arg)
{
PR_NOTICE("TUYA_PA5 irq trigger");
tuya_pin_irq_disable(TUYA_PA5);
}
void tuya_pa12_irq_cb(void *arg)
{
PR_NOTICE("TUYA_PA12 irq trigger");
PR_NOTICE("TUYA_PA5 irq enable");
tuya_pin_irq_enable(TUYA_PA5);
}
void tuya_pin_test(void)
{
STATIC UINT8_T tick = 0;
STATIC UINT8_T stat = TUYA_PIN_HIGH;
tuya_pin_init(TUYA_PA22, TUYA_PIN_MODE_OUT_PP_HIGH);
tuya_pin_init(TUYA_PA19, TUYA_PIN_MODE_OUT_PP_LOW);
tuya_pin_init(TUYA_PA14, TUYA_PIN_MODE_IN_PU);
tuya_pin_irq_init(TUYA_PA5, TUYA_PIN_MODE_IN_IRQ_FALL, tuya_pa5_irq_cb, NULL);
tuya_pin_irq_disable(TUYA_PA5);
tuya_pin_irq_init(TUYA_PA12, TUYA_PIN_MODE_IN_IRQ_FALL, tuya_pa12_irq_cb, TUYA_PA5);
while (1) {
if (++tick >= 3) {
tick = 0;
stat = stat ? TUYA_PIN_LOW : TUYA_PIN_HIGH;
tuya_pin_write(TUYA_PA22, stat);
}
if (tuya_pin_read(TUYA_PA14)) {
tuya_pin_write(TUYA_PA19, TUYA_PIN_HIGH);
} else {
tuya_pin_write(TUYA_PA19, TUYA_PIN_LOW);
}
}
}
#define tuya_hal_system_sleep(msTime)
System sleep
Definition: tuya_hal_system.h:55

UART

uart接口列表

函数名称 功能描述
int tuya_uart_init(tuya_uart_t *uart); 串口初始化
int tuya_uart_read(tuya_uart_t *uart, void *data, uint16_t len); 串口发送数据
int tuya_uart_write(tuya_uart_t *uart, void *data, uint16_t len); 串口读数据
int tuya_uart_control(tuya_uart_t *uart, uint8_t cmd, void *arg); 串口控制
int tuya_uart_deinit(tuya_uart_t *uart); 串口反初始化

串口访问端口

typedef enum {
TUYA_UART0 = 0x00,
TUYA_UART1,
TUYA_UART2,
TUYA_UART3,
} tuya_uart_port_t;

串口配置参数

typedef enum {
TUYA_UART_BAUDRATE_300 = 300,
TUYA_UART_BAUDRATE_600 = 600,
TUYA_UART_BAUDRATE_1200 = 1200,
TUYA_UART_BAUDRATE_2400 = 2400,
TUYA_UART_BAUDRATE_4800 = 4800,
TUYA_UART_BAUDRATE_9600 = 9600,
TUYA_UART_BAUDRATE_19200 = 19200,
TUYA_UART_BAUDRATE_38400 = 38400,
TUYA_UART_BAUDRATE_57600 = 57600,
TUYA_UART_BAUDRATE_74880 = 74880,
TUYA_UART_BAUDRATE_115200 = 115200,
TUYA_UART_BAUDRATE_230400 = 230400,
TUYA_UART_BAUDRATE_460800 = 460800,
TUYA_UART_BAUDRATE_921600 = 921600,
TUYA_UART_BAUDRATE_1500000 = 1500000,
TUYA_UART_BAUDRATE_1843200 = 1843200,
TUYA_UART_BAUDRATE_3686400 = 3686400,
} tuya_uart_baudrate_t;
typedef enum {
TUYA_UART_DATA_BIT5 = 0x05,
TUYA_UART_DATA_BIT6 = 0x06,
TUYA_UART_DATA_BIT7 = 0x07,
TUYA_UART_DATA_BIT8 = 0x08,
} tuya_uart_databits_t;
typedef enum {
TUYA_UART_STOP_BIT1 = 0x01,
TUYA_UART_STOP_BIT1_5 = 0x02,
TUYA_UART_STOP_BIT2 = 0x03,
} tuya_uart_stopbits_t;
typedef enum {
TUYA_UART_PARITY_NONE = 0,
TUYA_UART_PARITY_ODD = 1,
TUYA_UART_PARITY_EVEN = 2,
} tuya_uart_parity_t;

串口简化式配置宏

#define TUYA_UART_8N1_CFG(__UART, __BAUDRATE, __BUFSZ, __FLAG) \
(__UART)->cfg.baudrate = __BAUDRATE; \
(__UART)->cfg.flag = TUYA_DRV_INT_RX_FLAG | __FLAG; \
(__UART)->cfg.bufsz = __BUFSZ; \
(__UART)->cfg.databits = TUYA_UART_DATA_BIT8; \
(__UART)->cfg.stopbits = TUYA_UART_STOP_BIT1; \
(__UART)->cfg.parity = TUYA_UART_PARITY_NONE

串口结构体

struct tuya_uart {
tuya_drv_node_t node;
tuya_uart_cfg_t cfg;
tuya_uart_cb_t cb;
tuya_uart_ops_t *ops;
void *rxfifo;
};
typedef struct tuya_uart tuya_uart_t;

串口配置结构体

typedef struct {
uint16_t flag;
uint16_t bufsz;
tuya_uart_baudrate_t baudrate;
tuya_uart_databits_t databits;
tuya_uart_stopbits_t stopbits;
tuya_uart_parity_t parity;
} tuya_uart_cfg_t;

串口回调结构体

typedef struct {
int (*tx_finish) (tuya_uart_t *uart, void *buffer);
int (*rx_notify) (tuya_uart_t *uart, uint16_t size);
} tuya_uart_cb_t;

串口接口描述

串口初始化函数
int tuya_uart_init(tuya_uart_t *uart);
参数 描述
uart 串口句柄,需要初始化相关参数
返回 ——
OPRT_OK 初始化成功
其他错误码 执行失败
串口数据发送函数
int tuya_uart_write(tuya_uart_t *uart, void *data, uint16_t len);
参数 描述
uart 串口句柄
data 要发送数据的指针
len 要发送的数据字节长度
返回 ——
实际发送的数据长度
串口数据接收函数
int tuya_uart_read(tuya_uart_t *uart, void *data, uint16_t len);
参数 描述
uart 串口句柄
data 要接收数据的指针
len 要接收的数据字节长度
返回 ——
实际读取数据的长度
串口控制函数
int tuya_uart_control(tuya_uart_t *uart, uint8_t cmd, void *arg);
参数 描述
uart 串口句柄
cmd 命令控制字,可取值:TUYA_DRV_CONFIG_CMD
arg 控制的参数,类型: tuya_uart_cfg_t
返回 ——
OPRT_OK 控制成功
其他错误码 控制失败
串口反初始化函数
int tuya_uart_deinit(tuya_uart_t *uart);
参数 描述
uart 串口句柄
返回 ——
OPRT_OK 关闭成功
其他错误码 关闭失败

串口使用示例

#include "tuya_uart.h"
#define UART_BUFSZ 5
void tuya_uart_test(void)
{
int result;
uint8_t byte, size;
uint8_t buffer[UART_BUFSZ + 1];
tuya_uart_t *uart = (tuya_uart_t *) tuya_driver_find(TUYA_DRV_UART, TUYA_UART1);
if (NULL == uart) {
PR_DEBUG("tuya uart find failed");
}
TUYA_UART_8N1_CFG(uart, 115200, 256, 0);
tuya_uart_init(uart);
uint8_t data[] = "uart change baudrate start\r\n";
tuya_uart_write(uart, data, strlen(data));
for (;;) {
int len = tuya_uart_read(uart, &byte, 1);
PR_DEBUG_RAW("%c", byte);
tuya_uart_write(uart, &byte, 1);
if ('q' == byte) {
break;
}
}
TUYA_UART_8N1_CFG_INIT(&uart_cfg, 1500000, 256, 0);
result = tuya_uart_control(uart, TUYA_DRV_CONFIG_CMD, &uart_cfg);
if (OPRT_OK != result) {
PR_ERR("uart cfg failed", result);
}
uint8_t str[] = "uart change baudrate complete\r\n";
tuya_uart_write(uart, str, strlen(str));
for (;;) {
int len = tuya_uart_read(uart, &byte, 1);
PR_DEBUG_RAW("%c", byte);
tuya_uart_write(uart, &byte, 1);
if ('q' == byte) {
break;
}
}
}
Common process - driver uart

TIMER

定时器接口列表

函数名称 功能描述
int tuya_timer_init(tuya_timer_t *timer); 定时器初始化
int tuya_timer_start(tuya_timer_t *timer, uint32_t us); 启动定时器
int tuya_timer_stop(tuya_timer_t *timer); 停止定时器
int tuya_timer_deinit(tuya_timer_t *timer); 定时器关闭

定时器访问端口

typedef enum {
TUYA_TIMER0 = 0,
TUYA_TIMER1,
TUYA_TIMER2,
TUYA_TIMER3,
} tuya_timer_port_t;

定时器配置参数

typedef enum {
TUYA_TIMER_MODE_ONCE = 0,
TUYA_TIMER_MODE_PERIOD
} tuya_timer_mode_t;
typedef struct {
tuya_timer_mode_t mode;
tuya_timer_isr_cb cb;
void *arg;
} tuya_timer_cfg_t;

定时器回调

typedef void (*tuya_timer_isr_cb)(void *args);

定时器简化配置宏

#define TUYA_TIMER_CFG(__TIMER, __MODE, __CB, __ARG) \
(__TIMER)->cfg.mode = __MODE; \
(__TIMER)->cfg.cb = __CB; \
(__TIMER)->cfg.arg = __ARG

定时器结构体

struct tuya_timer {
tuya_drv_node_t node;
tuya_timer_cfg_t cfg;
tuya_timer_ops_t *ops;
};
typedef struct tuya_timer tuya_timer_t;

定时器接口描述

定时器初始化函数
int tuya_timer_init(tuya_timer_t *timer);
参数 描述
timer 定时器句柄,需要初始化定时器参数
返回 ——
OPRT_OK 初始化成功
其他错误码 执行失败
定时器启动函数
int tuya_timer_start(tuya_timer_t *timer, uint32_t us);
参数 描述
timer 定时器句柄
us 超时时间,单位微秒
返回 ——
OPRT_OK 启动成功
其他错误码 启动失败
定时器停止函数
int tuya_timer_stop(tuya_timer_t *timer);
参数 描述
timer 定时器句柄
返回 ——
OPRT_OK 停止成功
其他错误码 停止失败
定时器关闭函数
int tuya_timer_deinit(tuya_timer_t *timer);
参数 描述
timer 定时器句柄
返回 ——
OPRT_OK 关闭成功
其他错误码

定时器使用示例

#include "tuya_pin.h"
#include "tuya_timer.h"
static tuya_timer_t *timer;
static uint8_t led_blink = 1;
void tuya_timer0_cb(void *arg)
{
static uint32_t tick;
uint8_t *led = (uint8_t *)arg;
if (tick++ >= 200) {
tick = 0;
// *led = !*led;
led_blink = !led_blink;
tuya_pin_write(TUYA_PA22, led_blink);
}
}
void tuya_timer_test(void)
{
led_blink = TUYA_PIN_HIGH;
tuya_pin_init(TUYA_PA22, TUYA_PIN_MODE_OUT_PP_HIGH);
timer = (tuya_timer_t *)tuya_driver_find(TUYA_DRV_TIMER, TUYA_TIMER0);
TUYA_TIMER_CFG(timer, TUYA_TIMER_MODE_PERIOD, tuya_timer0_cb, &led_blink);
tuya_timer_init(timer);
tuya_timer_start(timer, 1000);
uint8_t duration = 0;
while (1) {
duration++;
if (duration == 3) {
tuya_timer_stop(timer);
tuya_timer_start(timer, 3000);
} else if (duration == 6) {
tuya_timer_stop(timer);
tuya_timer_start(timer, 1000);
duration = 0;
}
}
}
Common process - Initialization

PWM

pwm接口列表

函数名称 功能描述
int tuya_pwm_init(tuya_pwm_t *pwm); 初始化PWM
int tuya_pwm_start(tuya_pwm_t *pwm); 启动PWM
int tuya_pwm_stop(tuya_pwm_t *pwm); 停止PWM
int tuya_pwm_set(tuya_pwm_t *pwm, float frequency, float percent); 设置PWM频率和占空比
int tuya_pwm_frequency_set (tuya_pwm_t *pwm, float frequency); 设置PWM频率
int tuya_pwm_duty_set(tuya_pwm_t *pwm, float percent); 设置PWM占空比
int tuya_pwm_polarity_set (tuya_pwm_t *pwm, tuya_pwm_polarity_t polarity); 设置PWM初始极性
int tuya_pwm_deinit(tuya_pwm_t *pwm); 关闭PWM

PWM访问端口

typedef enum {
TUYA_PWM0 = 0x00,
TUYA_PWM1,
TUYA_PWM2,
TUYA_PWM3,
TUYA_PWM4,
TUYA_PWM5,
TUYA_PWM6,
TUYA_PWM7,
TUYA_PWM8,
} tuya_pwm_port_t;

PWM配置结构体

typedef struct {
uint8_t pin;
uint8_t polarity;
uint32_t period_ns;
uint32_t pulse_ns;
float percent;
} tuya_pwm_cfg_t;
typedef enum {
TUYA_PWM_POSITIVE = 0,
TUYA_PWM_NEGATIVE,
} tuya_pwm_polarity_t;

PWM简化配置宏

#define TUYA_PWM_CFG(__PWM, __PIN, __FREQUENCY, __PERCENT) \
(__PWM)->cfg.pin = __PIN; \
(__PWM)->cfg.period_ns = (uint32_t)1000000000 / (__FREQUENCY); \
(__PWM)->cfg.percent = __PERCENT; \
(__PWM)->cfg.pulse_ns = (uint32_t)((__PWM)->cfg.period_ns * (__PERCENT)); \
(__PWM)->cfg.polarity = TUYA_PWM_POSITIVE

PWM结构体

struct tuya_pwm {
tuya_drv_node_t node;
tuya_pwm_cfg_t cfg;
tuya_pwm_ops_t *ops;
};
typedef struct tuya_pwm tuya_pwm_t;

PWM接口描述

PWM初始化函数
int tuya_pwm_init(tuya_pwm_t *pwm);
参数 描述
pwm PWM句柄,需要初始化PWM参数
返回 ——
OPRT_OK 初始化成功
其他错误码 初始化失败
PWM启动函数
int tuya_pwm_start(tuya_pwm_t *pwm);
参数 描述
pwm PWM句柄
返回 ——
OPRT_OK 启动成功
其他错误码 启动失败
PWM停止函数
int tuya_pwm_stop(tuya_pwm_t *pwm);
参数 描述
pwm PWM句柄
返回 ——
OPRT_OK 停止成功
其他错误码 停止失败
PWM频率和占空比设置函数
int tuya_pwm_set(tuya_pwm_t *pwm, float frequency, float percent);
参数 描述
pwm PWM句柄
frequency PWM频率
percent PWM占空比,0-1
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败
PWM周期设置函数
int tuya_pwm_frequency_set(tuya_pwm_t *pwm, float frequency);
参数 描述
pwm PWM句柄
frequency PWM频率
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败
PWM脉宽设置函数
int tuya_pwm_duty_set(tuya_pwm_t *pwm, float percent);
参数 描述
pwm PWM句柄
percent PWM占空比,0-1
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败
PWM极性设置函数
int tuya_pwm_polarity_set(tuya_pwm_t *pwm, tuya_pwm_polarity_t polarity);
参数 描述
pwm PWM句柄
polarity PWM初始极性,@tuya_pwm_polarity_t中的枚举值
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败
PWM关闭函数
INT_T ty_pwm_deinit(TY_PWM_DEV_S *pwm);
参数 描述
pwm PWM句柄
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败

PWM使用示例

#include "tuya_pin.h"
#include "tuya_pwm.h"
static tuya_pwm_t *pwm[5];
void tuya_pwm_test(void)
{
UINT8_T pwm_pin[] = {
TUYA_PA14, TUYA_PA15, TUYA_PA0, TUYA_PA5, TUYA_PA12
};
#if 1
int i;
for (i = 0; i < 5; i++) {
pwm[i] = (tuya_pwm_t *)tuya_driver_find(TUYA_DRV_PWM, (tuya_pwm_port_t)i);
TUYA_PWM_CFG(pwm[i], pwm_pin[i], 10 * 1000, 0.1);
tuya_pwm_init(pwm[i]);
tuya_pwm_start(pwm[i]);
}
#else
pwm[0] = tuya_driver_find(TUYA_DRV_PWM, TUYA_PWM0);
TUYA_PWM_CFG(pwm[0], TUYA_PA14, 10 * 1000, 0.1);
tuya_pwm_init(pwm[0]);
tuya_pwm_start(pwm[0]);
pwm[1] = tuya_driver_find(TUYA_DRV_PWM, TUYA_PWM1);
TUYA_PWM_CFG(pwm[1], TUYA_PA15, 10 * 1000, 0.1);
tuya_pwm_init(pwm[1]);
tuya_pwm_start(pwm[1]);
pwm[2] = tuya_driver_find(TUYA_DRV_PWM, TUYA_PWM2);
TUYA_PWM_CFG(pwm[2], TUYA_PA0, 10 * 1000, 0.1);
tuya_pwm_init(pwm[2]);
tuya_pwm_start(pwm[2]);
pwm[3] = tuya_driver_find(TUYA_DRV_PWM, TUYA_PWM3);
TUYA_PWM_CFG(pwm[3], TUYA_PA5, 10 * 1000, 0.1);
tuya_pwm_init(pwm[3]);
tuya_pwm_start(pwm[3]);
pwm[4] = tuya_driver_find(TUYA_DRV_PWM, TUYA_PWM4);
TUYA_PWM_CFG(pwm[4], TUYA_PA12, 10 * 1000, 0.1);
tuya_pwm_init(pwm[4]);
tuya_pwm_start(pwm[4]);
#endif
PR_DEBUG("ns %d us %d", pwm[0]->cfg.period_ns, pwm[0]->cfg.period_ns / 1000);
uint8_t flag = 1;
float percent = TUYA_PWM_PERCENT(pwm[0]);
while (1) {
if (flag) {
if (percent < 1.0) {
percent += 0.005;
} else {
flag = 0;
continue;
}
} else {
if (percent > 0.005) {
percent -= 0.005;
} else {
flag = 1;
continue;
}
}
PR_NOTICE("percent = %d", (int)(percent * 1000));
for (UINT8_T i = 0; i < 5; i ++) {
tuya_pwm_duty_set(pwm[i], percent);
}
}
}

I2C

I2C接口列表

函数名称 功能描述
int tuya_i2c_init(tuya_i2c_t *i2c); I2C初始化
int tuya_sw_i2c_register(tuya_i2c_port_t port, tuya_i2c_sw_cfg_t *cfg); 注册软件I2C初始化
int tuya_i2c_control(tuya_i2c_t *i2c, uint8_t cmd, void *arg); I2C自定义数据发送
int tuya_i2c_deinit(tuya_i2c_t *i2c); I2C关闭
int tuya_i2c_master_send(tuya_i2c_t *i2c, uint16_t addr, uint16_t flags, void *buf, uint16_t count); I2C主机发送函数
int tuya_i2c_master_recv(tuya_i2c_t *i2c, uint16_t addr, uint16_t flags, void *buf, uint16_t count); I2C主机接收函数

I2C访问端口

typedef enum {
TUYA_I2C0 = 0,
TUYA_I2C1,
TUYA_I2C2,
TUYA_I2C3,
} tuya_i2c_port_t;

I2C配置参数

#define TUYA_I2C_WR 0x0000
#define TUYA_I2C_RD (1 << 0)
#define TUYA_I2C_ADDR_10BIT (1 << 2)
#define TUYA_I2C_NO_START (1 << 4)
#define TUYA_I2C_IGNORE_NACK (1 << 5)
#define TUYA_I2C_NO_READ_ACK (1 << 6)
#define TUYA_I2C_NO_WRITE_ACK (1 << 7)
typedef enum {
TUYA_I2C_MODE_MASTER = 0,
TUYA_I2C_MODE_SLAVE,
} tuya_i2c_mode_t;

I2C配置结构体

typedef struct {
uint8_t sda_pin;
uint8_t scl_pin;
uint32_t delay_count;
uint32_t timeout;
} tuya_i2c_sw_cfg_t;
typedef struct {
uint8_t mode;
uint16_t dev_addr;
} tuya_i2c_cfg_t;
typedef struct {
uint16_t addr;
uint16_t flags;
uint16_t len;
uint8_t *buf;
} tuya_i2c_msg_t;

I2C简化配置宏

#define TUYA_I2C_MASTER_CFG(__I2C, __ADDR) \
(__I2C)->cfg.dev_addr = __ADDR; \
(__I2C)->cfg.mode = TUYA_I2C_MODE_MASTER \
#define TUYA_I2C_SW_CFG_INIT(__CFG, __SCL, __SDA, __DELAY) \
(__CFG)->scl_pin = __SCL; \
(__CFG)->sda_pin = __SDA; \
(__CFG)->delay_count = __DELAY; \
(__CFG)->timeout = 100

I2C结构体

struct tuya_i2c {
tuya_drv_node_t node;
tuya_i2c_cfg_t cfg;
tuya_i2c_ops_t *ops;
};
typedef struct tuya_i2c tuya_i2c_t;

I2C接口描述

软件I2C注册函数
int tuya_sw_i2c_register(tuya_i2c_port_t port, tuya_i2c_sw_cfg_t *cfg);
参数 描述
port 需要注册的端口号,@tuya_i2c_port_t
cfg 需要设置的配置, @tuya_i2c_sw_cfg_t
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败
I2C初始化函数
int tuya_i2c_init(tuya_i2c_t *i2c);
参数 描述
i2c I2C句柄(需要查找)
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败
I2C主机数据发送函数
int tuya_i2c_master_send(tuya_i2c_t *i2c, uint16_t addr, uint16_t flags, void *buf, uint16_t count);
参数 描述
i2c I2C句柄
addr 设备地址
flags I2C标志
buf 数据发送缓冲区指针
count 数据长度
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败
I2C主机数据接收函数
int tuya_i2c_master_recv(tuya_i2c_t *i2c, uint16_t addr, uint16_t flags, void *buf, uint16_t count);
参数 描述
i2c I2C句柄
addr 设备地址
flags I2C标志
buf 数据接收缓冲区指针
count 数据长度
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败
I2C关闭函数
int tuya_i2c_deinit(tuya_i2c_t *i2c);
参数 描述
i2c I2C句柄
返回 ——
OPRT_OK 执行成功
其他错误码 执行失败

软件I2C使用示例

/*============================ INCLUDES ======================================*/
#include "tuya_pin.h"
#include "tuya_i2c.h"
/*============================ TYPES =========================================*/
typedef struct {
tuya_i2c_t *i2c;
} sm2135e_dev_t;
typedef struct {
tuya_i2c_t *i2c;
} sm16726b_dev_t;
/*============================ PROTOTYPES ====================================*/
void sm2135_init(sm2135e_dev_t *dev);
void sm2135_rgb_set(sm2135e_dev_t *dev, uint8_t r, uint8_t g, uint8_t b);
void sm2135_cw_set(sm2135e_dev_t *dev, uint8_t c, uint8_t w);
void sm16726b_init(sm16726b_dev_t *dev);
void sm2135_test(void);
void sm16726b_test(void);
/*============================ IMPLEMENTATION ================================*/
static sm2135e_dev_t sm2135e_dev;
static sm2135e_dev_t sm16726b_dev;
void tuya_sw_i2c_test(void)
{
tuya_i2c_sw_cfg_t sw_cfg;
TUYA_I2C_SW_CFG_INIT(&sw_cfg, TUYA_PA14, TUYA_PA15, 1);
tuya_sw_i2c_register(TUYA_I2C0, &sw_cfg);
TUYA_I2C_SW_CFG_INIT(&sw_cfg, TUYA_PA19, TUYA_PA22, 1);
tuya_sw_i2c_register(TUYA_I2C1, &sw_cfg);
sm2135_init(&sm2135e_dev);
sm16726b_init(&sm16726b_dev);
while(1) {
sm16726b_test();
sm2135_test();
}
}
void sm16726b_init(sm16726b_dev_t *dev)
{
uint8_t buffer[2];
dev->i2c = tuya_driver_find(TUYA_DRV_I2C, TUYA_I2C1);
TUYA_I2C_MASTER_CFG(dev->i2c, 0x00);
tuya_i2c_init(dev->i2c);
}
void sm16726b_rgb_set(sm16726b_dev_t *dev, uint8_t r, uint8_t g, uint8_t b)
{
uint8_t buffer[7 + 3 + 1];
memset(buffer, 0, 6);
buffer[6] = 0x01;
buffer[7] = r;
buffer[8] = g;
buffer[9] = b;
buffer[10] = 0xFF;
tuya_i2c_master_send(dev->i2c, 0x00, TUYA_I2C_NO_START | TUYA_I2C_NO_WRITE_ACK, buffer, 11);
}
void sm16726b_test(void)
{
sm16726b_rgb_set(&sm16726b_dev, 255, 0, 0);
sm16726b_rgb_set(&sm16726b_dev, 0, 255, 0);
sm16726b_rgb_set(&sm16726b_dev, 0, 0, 255);
sm16726b_rgb_set(&sm16726b_dev, 0, 0, 0);
// tuya_hal_system_sleep(500);
}
void sm2135_init(sm2135e_dev_t *dev)
{
uint8_t buffer[2];
dev->i2c = tuya_driver_find(TUYA_DRV_I2C, TUYA_I2C0);
TUYA_I2C_MASTER_CFG(dev->i2c, 0x00);
tuya_i2c_init(dev->i2c);
buffer[0] = 0xC0;
buffer[1] = 0x20 | 0x04;
tuya_i2c_master_send(dev->i2c, 0x00, TUYA_I2C_NO_START | TUYA_I2C_NO_WRITE_ACK, buffer, 2);
}
void sm2135_rgb_set(sm2135e_dev_t *dev, uint8_t r, uint8_t g, uint8_t b)
{
uint8_t buffer[5];
buffer[0] = 0xC1;
buffer[1] = 0;
buffer[2] = r;
buffer[3] = g;
buffer[4] = b;
tuya_i2c_master_send(dev->i2c, 0x00, TUYA_I2C_NO_START | TUYA_I2C_IGNORE_NACK, buffer, 5);
}
void sm2135_cw_set(sm2135e_dev_t *dev, uint8_t c, uint8_t w)
{
uint8_t buffer[3];
buffer[0] = 0xC1;
buffer[1] = 0x80;
tuya_i2c_master_send(dev->i2c, 0x00, TUYA_I2C_NO_START | TUYA_I2C_IGNORE_NACK, buffer, 2);
buffer[0] = 0xC5;
buffer[1] = c;
buffer[2] = w;
tuya_i2c_master_send(dev->i2c, 0x00, TUYA_I2C_NO_START | TUYA_I2C_IGNORE_NACK, buffer, 3);
}
void sm2135_test(void)
{
sm2135_rgb_set(&sm2135e_dev, 255, 0, 0);
sm2135_rgb_set(&sm2135e_dev, 0, 255, 0);
sm2135_rgb_set(&sm2135e_dev, 0, 0, 255);
// sm2135_rgb_set(&sm2135e_dev, 0, 0, 0);
sm2135_cw_set(&sm2135e_dev, 255, 0);
sm2135_cw_set(&sm2135e_dev, 0, 255);
sm2135_cw_set(&sm2135e_dev, 0, 0);
// tuya_hal_system_sleep(500);
}