Last Updated on : 2024-11-20 02:14:53download
API files
The I2C API is located in ty_i2c.h
. The driver code for different chip platforms is located in ty_i2c_xxxx.c
.
tuya_ble_sdk_demo
└── board
├── include
| └── ty_i2c.h
├── xxxx /* xxxx represents the chip platform, such as TLSR825x */
| └── ty_board_xxxx /* xxxx represents the chip platform, such as ty_board_tlsr825x */
| └── ty_i2c_xxxx.c /* xxxx represents the chip platform, such as ty_i2c_tlsr825x.c */
└── board.h
Demo files
File structure of tuya_board_api_demo:
tuya_ble_sdk_demo
├── app /* API example */
| ├── include
| | └── ty_board_demo
| | | ├── demo_config.h /* Demo configuration file */
| | | └── ty_i2c_demo.h /* I2C sample code */
| | ├── tuya_ble_board_api_demo.h /* Entry point to Board API example */
| | └── tuya_ble_sdk_demo.h /* Entry point to tuya_ble_sdk application */
| └── src
| ├── ty_board_demo
| | └── ty_i2c_demo.c /* I2C sample code */
| ├── tuya_ble_board_api_demo.c /* Entry point to Board API example */
| └── tuya_ble_sdk_demo.c /* Entry point to tuya_ble_sdk application */
└── board /* Example of modifying API code */
Modify demo_config.h
to toggle to the I2C example.
#define BOARD_API_DEMO BOARD_API_I2C
Function name | Description |
---|---|
ty_i2c_init | Initialize the I2C. |
ty_i2c_start | I2C hardware: Start I2C transmission. |
ty_i2c_stop | I2C hardware: Stop I2C transmission. |
ty_i2c_control | I2C hardware: Control the I2C. |
ty_i2c_uninit | I2C hardware: Disable the I2C. |
ty_i2c_send | I2C hardware: Send data. |
i2c_send_bytes | I2C software: Send multiple-byte data. |
i2c_rcv_bytes | I2C software: Receive multiple-byte data. |
i2c_soft_cfg | I2C software: Configure the peripheral register. |
i2c_soft_gpio_init | I2C software: Initialize the I2C pin. |
i2c_start | I2C software: Send the start signal. |
i2c_stop | I2C software: Send the stop signal. |
i2c_delay | I2C software: Delay in microseconds. |
Function name | ty_i2c_init |
---|---|
Function prototype | uint32_t ty_i2c_init(void); |
Description | Initialize the I2C. |
Parameter | None |
Return value | 0 : Success. Others: Failure. |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | ty_i2c_start |
---|---|
Function prototype | uint32_t ty_i2c_start(void); |
Description | I2C hardware: Start I2C transmission. |
Parameter | None |
Return value | 0 : Success. Others: Failure. |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | ty_i2c_stop |
---|---|
Function prototype | uint32_t ty_i2c_stop(void); |
Description | I2C hardware: Stop I2C transmission. |
Parameter | None |
Return value | 0 : Success. Others: Failure. |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | ty_i2c_control |
---|---|
Function prototype | uint32_t ty_i2c_control(uint8_t cmd, void* arg); |
Description | I2C hardware: Control the I2C. |
Parameter | cmd [in]: The control command. arg [in]: The parameter of the command. |
Return value | 0 : Success. Others: Failure. |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | ty_i2c_uninit |
---|---|
Function prototype | uint32_t ty_i2c_uninit(void); |
Description | I2C hardware: Disable the I2C. |
Parameter | None |
Return value | 0 : Success. Others: Failure. |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | ty_i2c_send |
---|---|
Function prototype | uint32_t ty_i2c_send(const uint8_t addr, const uint8_t* buf, uint32_t size); |
Description | I2C hardware: Send data. |
Parameter | addr [in]: The address. buf [in]: Data to be sent. size [in]: Size of the data. |
Return value | 0 : Success. Others: Failure. |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | i2c_send_bytes |
---|---|
Function prototype | void i2c_send_bytes(uint8_t adderss_cmd, uint8_t *buff, uint8_t len); |
Description | I2C software: Send multiple-byte data. |
Parameter | adderss_cmd [in]: The peripheral address and the read-write command. buff [in]: Data to be sent. len [in]: The length of the data. |
Return value | None |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | i2c_rcv_bytes |
---|---|
Function prototype | void i2c_rcv_bytes(uint8_t adderss_cmd, uint8_t *buff, uint8_t len); |
Description | I2C software: Receive multiple-byte data. |
Parameter | adderss_cmd [in]: The peripheral address and the read-write command. buff [out]: Data received. len [in]: The length of the data. |
Return value | None |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | i2c_soft_cfg |
---|---|
Function prototype | void i2c_soft_cfg(uint8_t adderss_cmd, uint8_t reg_addr, uint8_t data); |
Description | I2C software: Configure the peripheral register. |
Parameter | adderss_cmd [in]: The peripheral address and the read-write command. reg_addr [in]: The register address. data [in]: The register value. |
Return value | None |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | i2c_soft_gpio_init |
---|---|
Function prototype | void i2c_soft_gpio_init(void); |
Description | I2C software: Initialize the I2C pin. |
Parameter | None |
Return value | None |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | i2c_start |
---|---|
Function prototype | void i2c_start(void); |
Description | I2C software: Send the start signal. |
Parameter | None |
Return value | None |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | i2c_stop |
---|---|
Function prototype | void i2c_stop(void); |
Description | I2C software: Send the stop signal. |
Parameter | None |
Return value | None |
Notes | You can add or modify functions, parameters, and return values as needed. |
Function name | i2c_delay |
---|---|
Function prototype | void i2c_delay(unsigned long tim_1us); |
Description | I2C software: Delay in microseconds. |
Parameter | tim_1us[in]: Time in microseconds. |
Return value | None |
Notes | None |
None.
Use TLSR825x as an example. You can add I2C API functions or call APIs provided by the chip vendor in the application code.
ty_i2c.h
/* ! This macro is used to distinguish between I2C software and I2C hardware. The I2C software/hardware interfaces have been specialized in this demo, so this macro can be ignored. */
#define USE_SOFT_I2C 0
/* ! Modified the type of addr, and added the addr_len parameter and the ty_i2c_rcv function. */
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
/* ! Configure the I2C pin. SLAVE_ADDR_WRITE is added for I2C hardware initialization. */
#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)
/* ! Modified the input parameters of 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;
}
/* ! Modified the parameters and content of the data sending function. The addr parameter represents the register address, and addr_len represents the number of bytes of the address. */
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;
}
/* ! Added the data receiving function that uses the same parameters as the data sending function. */
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;
}
Description
Use I2C hardware or software to drive the peripherals to regularly collect data from sensors.
Sample code
The sample code uses the TLSR825x platform.
I2C_API_DEMO_SHT3X
- sample driver for the temperature and humidity sensor SHT30-DIS
The 16-bit commands of SHT3x can be used as register addresses.
#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
- sample driver for the motion sensor MPU6050
Sensor documents:
#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, ®_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, ®_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);
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback