add TH-05

This commit is contained in:
pvvx 2024-01-23 19:28:49 +03:00
parent 6b6b8a1155
commit 84eb8e9f2d
25 changed files with 9749 additions and 6199 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -1,23 +1,23 @@
# BTHome THB2, BTH01, TH-05
Custom firmware for Tuya [THB2](https://pvvx.github.io/THB2) and [BTH01](https://pvvx.github.io/BTH01/).
Custom firmware for Tuya [THB2](https://pvvx.github.io/THB2), [BTH01](https://pvvx.github.io/BTH01/), [TH-05](https://pvvx.github.io/TH-05).
* Проект в начальной стадии разработки, до появления функционального OTA.
* Тестовый [PHY62x2BTHome.html](https://pvvx.github.io/THB2/web/PHY62x2BTHome.html)
В плане проекта предусматривается дальнейшая поддержка [TH-05](https://pvvx.github.io/TH-05).
Прошивка для THB2 (файл bin\BOOT_THB2_v0x.hex).
Прошивка для THB2 (файл BOOT_THB2_v06.hex).
Прошивка для BTH01 (файл bin\BOOT_BTH01_v0x.hex).
Прошивка для BTH01 (файл BOOT_BTH01_v06.hex).
Прошивка для TH05 (файл bin\BOOT_TH05_v0x.hex).
## Основные характеристики:
* Интервал BLE рекламы в формате BTHome v2 составляет 5 секунд.
* Опрос датчика влажности и температуры производится каждый второй интервал BLE рекламы - период составляет 10 секунд.
* Интервал BLE рекламы в формате BTHome v2 равен 5 секундам.
* Опрос датчика влажности и температуры производится каждый второй интервал BLE рекламы - период 10 секунд.
* Измерение напряжения батареи производится каждую минуту.
* Кнопка используется для быстрого подключения к старым BT-адаптерам. Нажатие кнопки переключает интервал BLE рекламы на более короткий период. Действие продолжится 60 секунд, затем интервал восстановится.
* Измеренное среднее потребление от источника в 3.3В при сканировании термометра в пассивном режиме составляет до 7.9 мкА.
* Измеренное среднее потребление от источника в 3.3В при сканировании термометров THB2 и BTH01 в пассивном режиме составляет до 7.9 мкА. Для TH-05 21 мкА.
## Прошивка:

Binary file not shown.

3002
bin/BOOT_BTH01_v07.hex Normal file

File diff suppressed because it is too large Load diff

3056
bin/BOOT_TH05_v07.hex Normal file

File diff suppressed because it is too large Load diff

2999
bin/BOOT_THB2_v07.hex Normal file

File diff suppressed because it is too large Load diff

BIN
bin/BTH01_v07.bin Normal file

Binary file not shown.

BIN
bin/TH05_v07.bin Normal file

Binary file not shown.

BIN
bin/THB2_v07.bin Normal file

Binary file not shown.

View file

@ -21,6 +21,7 @@ SRC_PRJ += thb2_main.c
SRC_PRJ += thb2_peripheral.c
SRC_PRJ += thservice.c
SRC_PRJ += flash_eep.c
SRC_PRJ += lcd_th05.c
SRC_PRJ += ble_ota.c
INCLUDES = -I$(SRC_PATH)

View file

@ -1,5 +1,5 @@
@set PATH=D:\MCU\GNU_Tools_ARM_Embedded\13.2.rel1\bin;%PATH%
@set SWVER=_v06
@set SWVER=_v07
@del /Q "build\THB2%SWVER%.hex"
@del /Q "build\THB2%SWVER%.bin"
@mkdir .\bin
@ -14,7 +14,6 @@
@if not exist "build\BTH01%SWVER%.hex" goto :error
@copy "build\BTH01%SWVER%.bin" .\bin
@del /Q "build\BOOT_THB2%SWVER%.hex"
@mkdir .\bin
@make -s clean
@make -s -j PROJECT_NAME=BOOT_THB2%SWVER% BOOT_OTA=1 POJECT_DEF="-DDEVICE=DEVICE_THB2"
@if not exist "build\BOOT_THB2%SWVER%.hex" goto :error
@ -24,6 +23,18 @@
@make -s -j PROJECT_NAME=BOOT_BTH01%SWVER% BOOT_OTA=1 POJECT_DEF="-DDEVICE=DEVICE_BTH01"
@if not exist "build\BOOT_BTH01%SWVER%.hex" goto :error
@copy "build\BOOT_BTH01%SWVER%.hex" .\bin
@del /Q "build\TH05%SWVER%.hex"
@del /Q "build\TH05%SWVER%.bin"
@mkdir .\bin
@make -s clean
@make -s -j PROJECT_NAME=TH05%SWVER% POJECT_DEF="-DDEVICE=DEVICE_TH05"
@if not exist "build\TH05%SWVER%.hex" goto :error
@copy "build\TH05%SWVER%.bin" .\bin
@del /Q "build\BOOT_TH05%SWVER%.hex"
@make -s clean
@make -s -j PROJECT_NAME=BOOT_TH05%SWVER% BOOT_OTA=1 POJECT_DEF="-DDEVICE=DEVICE_TH05"
@if not exist "build\BOOT_TH05%SWVER%.hex" goto :error
@copy "build\BOOT_TH05%SWVER%.hex" .\bin
@exit
:error
@echo "Error!"

View file

@ -262,7 +262,7 @@ int ota_parser(unsigned char *pout, unsigned char *pmsg, unsigned int msg_size)
__ATTR_SECTION_XIP__
static uint32_t start_app(void) {
uint32_t i;
app_info_t info_app;
app_info_seg_t info_seg;
uint32_t info_seg_faddr = FADDR_APP_SEC;
@ -270,23 +270,31 @@ static uint32_t start_app(void) {
spif_read(info_seg_faddr, (uint8_t*)&info_app, sizeof(info_app));
if(info_app.flag == START_UP_FLAG) {
if(info_app.seg_count <= 15) {
while(info_app.seg_count) {
info_seg_faddr += sizeof(info_app);
spif_read(info_seg_faddr, (uint8_t*)&info_seg, sizeof(info_seg));
i = info_app.seg_count;
while(i--) {
if(info_app.start_addr == 0xffffffff) // если не назначен
// берется значение из первого сегмента отличного от -1
info_app.start_addr = info_seg.waddr;
info_seg.faddr += FADDR_START_ADDR;
info_seg.size &= 0x000fffff;
if (info_seg.waddr != info_seg.faddr // не XIP
&& info_seg.size < (128*1024)) { // < 128k
osal_memcpy((void *)info_seg.waddr, (void *)info_seg.faddr, info_seg.size);
}
info_app.seg_count--;
}
}
if(info_app.start_addr == 0xffffffff) {
info_app.start_addr = 0;
if(info_app.start_addr != 0xffffffff) {
while(info_app.seg_count) {
info_seg_faddr += sizeof(info_app);
spif_read(info_seg_faddr, (uint8_t*)&info_seg, sizeof(info_seg));
if(info_app.start_addr == 0xffffffff) // если не назначен
// берется значение из первого сегмента отличного от -1
info_app.start_addr = info_seg.waddr;
info_seg.faddr += FADDR_START_ADDR;
info_seg.size &= 0x000fffff;
if (info_seg.waddr != info_seg.faddr // не XIP
//&& info_seg.waddr < 0x11000000
//&& info_seg.waddr > 0x11020000
&& info_seg.size < (128*1024)) { // < 128k
osal_memcpy((void *)info_seg.waddr, (void *)info_seg.faddr, info_seg.size);
}
info_app.seg_count--;
}
} else
info_app.start_addr = 0;
}
} else
info_app.start_addr = 0;

View file

@ -25,17 +25,20 @@ extern "C"
* CONSTANTS
*/
#define DEF_ADV_INERVAL 8000 // = 5 sec, actual time = advInt * 625us
#define DEF_ADV_INERVAL_MS ((DEF_ADV_INERVAL*625)/1000) // 5000 ms
#define DEF_CON_ADV_INERVAL 2500 // 1.5625 sec
#define DEF_ADV_INERVAL 8000 // = 5 sec, actual time = advInt * 625us
#define DEF_ADV_INERVAL_MS ((DEF_ADV_INERVAL*625)/1000) // 5000 ms
#define DEF_CON_ADV_INERVAL 2500 // 1.5625 sec
#define DEF_CON_ADV_INERVAL_MS ((DEF_CON_ADV_INERVAL*625)/1000) // 1562 ms
#define DEF_OTA_ADV_INERVAL 1600 // 1 sec
#define DEF_OTA_ADV_INERVAL_MS ((DEF_OTA_ADV_INERVAL*625)/1000) // 1000 ms
// How often to perform periodic event
#define SBP_PERIODIC_EVT_PERIOD 5000
#define DEVINFO_SYSTEM_ID_LEN 8
#define DEVINFO_SYSTEM_ID 0
#define DEVINFO_SYSTEM_ID_LEN 8
#define DEVINFO_SYSTEM_ID 0
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
// Whether to enable automatic parameter update request when a connection is formed
#define DEFAULT_ENABLE_UPDATE_REQUEST TRUE

View file

@ -26,6 +26,7 @@
#include "devinfoservice.h"
#include "ble_ota.h"
#include "thb2_peripheral.h"
#include "lcd_th05.h"
/*********************************************************************/
#define SEND_DATA_SIZE 16
@ -70,13 +71,13 @@ int cmd_parser(uint8_t * obuf, uint8_t * ibuf, uint32_t len) {
osal_memcpy(&thsensor_cfg.coef, &ibuf[1], len);
flash_write_cfg(&thsensor_cfg.coef, EEP_ID_CFS, sizeof(thsensor_cfg.coef));
}
osal_memcpy(&obuf[1], &thsensor_cfg, thsensor_cfg_size);
olen = thsensor_cfg_size + 1;
osal_memcpy(&obuf[1], &thsensor_cfg, thsensor_cfg_send_size);
olen = thsensor_cfg_send_size + 1;
} else if (cmd == CMD_ID_CFS_DEF) { // Get/Set default sensor config
osal_memset(&thsensor_cfg, 0, thsensor_cfg_size);
osal_memset(&thsensor_cfg, 0, thsensor_cfg_send_size);
init_sensor();
osal_memcpy(&obuf[1], &thsensor_cfg, thsensor_cfg_size);
olen = thsensor_cfg_size + 1;
osal_memcpy(&obuf[1], &thsensor_cfg, thsensor_cfg_send_size);
olen = thsensor_cfg_send_size + 1;
} else if (cmd == CMD_ID_SERIAL) {
osal_memcpy(&obuf[1], devInfoSerialNumber, sizeof(devInfoSerialNumber)-1);
olen = 1 + sizeof(devInfoSerialNumber)-1;
@ -100,7 +101,17 @@ int cmd_parser(uint8_t * obuf, uint8_t * ibuf, uint32_t len) {
write_reg(OTA_MODE_SELECT_REG, ibuf[1]);
}
hal_system_soft_reset();
#if (DEV_SERVICES & SERVICE_SCREEN)
} else if (cmd == CMD_ID_LCD_DUMP) { // Get/set lcd buf
if (--len > sizeof(display_buff))
len = sizeof(display_buff);
if (len) {
osal_memcpy(display_buff, &ibuf[1], len);
update_lcd();
}
osal_memcpy(&obuf[1], display_buff, sizeof(display_buff));
olen = 1 + sizeof(display_buff);
#endif
//---------- Debug commands (unsupported in different versions!):
} else if (cmd == CMD_ID_EEP_RW && len > 2) {

View file

@ -67,8 +67,8 @@ void test_config(void) {
if(cfg.advertising_interval == 0)
cfg.advertising_interval = 1;
if(cfg.measure_interval == 0)
cfg.measure_interval = 1;
if(cfg.measure_interval < 2)
cfg.measure_interval = 2;
adv_wrk.measure_interval_ms = cfg.advertising_interval * cfg.measure_interval * 625 / 10;
}

View file

@ -11,7 +11,7 @@
#include "types.h"
#ifndef APP_VERSION
#define APP_VERSION 0x06 // BCD
#define APP_VERSION 0x07 // BCD
#endif
/*
@ -38,7 +38,7 @@
#define DEVICE_TH05 21
#ifndef DEVICE
#define DEVICE DEVICE_BTH01
#define DEVICE DEVICE_THB2
#endif
// supported services by the device (bits)
@ -128,13 +128,15 @@
#define USE_RS_SENSOR 0
#define USE_SECREEN 1
#define I2C_SDA GPIO_P33 // CHT8305_SDA
#define I2C_SCL GPIO_P34 // CHT8305_SCL
#define I2C_SDA GPIO_P33 // AHT20_SDA
#define I2C_SCL GPIO_P34 // AHT20_SCL
#define GPIO_SPWR GPIO_P00 // питание сенсора CHT8305_VDD
#define GPIO_KEY GPIO_P14
#define GPIO_LED GPIO_P15
#define LED_ON 1
#define LED_OFF 0
#define GPIO_LPWR GPIO_P02 // питание LCD драйвера
//#define GPIO_LED GPIO_P20
//#define LED_ON 1
//#define LED_OFF 0
#define DEF_MODEL_NUMBER_STR "TH05"
#define DEF_HARDWARE_REVISION "0001"

View file

@ -0,0 +1,257 @@
/*
* lcd_th05.c
*
* Created on: 23 янв. 2024 г.
* Author: pvvx
*/
#include <string.h>
#include "types.h"
#include "config.h"
#include "OSAL.h"
#include "gpio.h"
#include "rom_sym_def.h"
#include "i2c.h"
#include "sensor.h"
#include "lcd_th05.h"
#define SET_I2C_SPEED 400 // 100 or 400 kHz
#define I2C_WAIT_ms 1
/* 0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F*/
const uint8_t display_numbers[] = {
// 76543210
0b011110011, // 0
0b000000011, // 1
0b010110101, // 2
0b010010111, // 3
0b001000111, // 4
0b011010110, // 5
0b011110110, // 6
0b000010011, // 7
0b011110111, // 8
0b011010111, // 9
0b001110111, // A
0b011100110, // b
0b011110000, // C
0b010100111, // d
0b011110100, // E
0b001110100 // F
};
#define LCD_SYM_H 0b001100111 // "H"
#define LCD_SYM_h 0b001100110 // "h"
#define LCD_SYM_i 0b000100000 // "i"
#define LCD_SYM_L 0b011100000 // "L"
#define LCD_SYM_o 0b010100110 // "o"
#define LCD_SYM_t 0b011100100 // "t"
#define LCD_SYM_0 0b011110011 // "0"
#define LCD_SYM_a 0b011110110 // 'a'
#define lcd_i2c_addr 0x3E
uint8_t display_buff[LCD_BUF_SIZE] = {
LCD_SYM_o, LCD_SYM_o, LCD_SYM_o,
};
uint8_t display_out_buff[LCD_BUF_SIZE+1];
/* blink off: display_out_buff[0] = 0xf0, on: display_out_buff[0] = 0xf2 */
const uint8_t lcd_init_cmd[] = {
// LCD controller initialize:
//0xC8, // Mode Set (MODE SET): Display enable, 1/3 Bias
0xD8, // Mode Set (MODE SET): Display enable, 1/3 Bias, power saving
0x80, // load data pointer
0xF0, // blink control 0xf2
0x60,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
};
/*
* TH-05 LCD buffer: byte.bit
--0.4-- --1.4-- --2.4-- BAT
| | | | | | | 3.6
| 0.6 0.0 1.6 1.0 2.6 2.0
| | | | | | | o 3.5
0.3 --0.2-- --1.2-- --2.2-- +--- 3.5
| | | | | | | 3.5|
| 0.5 0.1 1.5 1.1 2.5 2.1 ---- 3.7
| | | | | | | 3.5|
--0.7-- --1.7-- * --2.7-- ---- 2.3
1.3
--4.4-- --5.4--
| | | |
3.0 3.0 4.6 4.0 5.6 5.0
/ \ / \ | | | |
3.4( \_/ 3.2 \_/ )3.4 --4.2-- --5.2--
3.2 / \ 3.2 | | | |
\_/ 4.5 4.1 5.5 5.1 %
3.0 | | | | 5.3
--4.7-- --5.7--
OO 4.3
None: 3.1, 3.3
*/
/* 0x0 = " "
* 0x1 = "°Г"
* 0x2 = " _"
* 0x3 = "°C"
* 0x4 = " -"
* 0x5 = "°F"
* 0x6 = " ="
* 0x7 = "°E" */
void show_temp_symbol(uint8_t symbol) {
display_buff[2] &= ~BIT(3);
display_buff[3] &= ~(BIT(7)|BIT(5)) ;
display_buff[2] |= (symbol << 2) & BIT(3);
display_buff[3] |= (symbol << 5) & (BIT(7)|BIT(5));
}
/* 0 = " " off,
* 1 = " ^_^ " happy
* 2 = " -^- " sad
* 3 = " ooo "
* 4 = "( )"
* 5 = "(^_^)" happy
* 6 = "(-^-)" sad
* 7 = "(ooo)" */
void show_smiley(uint8_t state) {
display_buff[3] &= ~0x15;
state = (state & 1) | ((state << 1) & 4) | ((state << 2) & 0x10);
display_buff[3] |= state;
}
void show_ble_symbol(bool state) {
if (state)
display_buff[4] |= BIT(3);
else
display_buff[4] &= ~BIT(3);
}
void show_battery_symbol(bool state) {
if (state)
display_buff[3] |= BIT(6);
else
display_buff[3] &= ~BIT(6);
}
void show_big_number_x10(int16_t number) {
display_buff[2] &= BIT(3); // F/C
if (number > 19995) {
display_buff[0] = LCD_SYM_H; // "H"
display_buff[1] = LCD_SYM_i; // "i"
} else if (number < -995) {
display_buff[0] = LCD_SYM_L; // "L"
display_buff[1] = LCD_SYM_o; // "o"
} else {
display_buff[0] = 0;
display_buff[1] = 0;
/* number: -995..19995 */
if (number > 1995 || number < -95) {
display_buff[1] = 0; // no point, show: -99..1999
if (number < 0){
number = -number;
display_buff[0] = BIT(2); // "-"
}
number = (number + 5) / 10; // round(div 10)
} else { // show: -9.9..199.9
display_buff[1] = BIT(3); // point,
if (number < 0){
number = -number;
display_buff[0] = BIT(2); // "-"
}
}
/* number: -99..1999 */
if (number > 999) display_buff[0] |= BIT(3); // "1" 1000..1999
if (number > 99) display_buff[0] |= display_numbers[number / 100 % 10];
if (number > 9) display_buff[1] |= display_numbers[number / 10 % 10];
else display_buff[1] |= LCD_SYM_0; // "0"
display_buff[2] = display_numbers[number %10];
}
}
/* -9 .. 99 */
void show_small_number(int16_t number, bool percent) {
display_buff[4] &= BIT(3); // connect
display_buff[5] = percent? BIT(3) : 0;
if (number > 99) {
display_buff[4] |= LCD_SYM_i; // "i"
display_buff[5] |= LCD_SYM_H; // "H"
} else if (number < -9) {
display_buff[4] |= LCD_SYM_o; // "o"
display_buff[5] |= LCD_SYM_L; // "L"
} else {
if (number < 0) {
number = -number;
display_buff[4] = BIT(2); // "-"
}
if (number > 9) display_buff[4] |= display_numbers[number / 10 % 10];
display_buff[5] |= display_numbers[number %10];
}
}
#if USE_CLOCK
void show_clock(void) {
uint32_t tmp = utc_time_sec / 60;
uint32_t min = tmp % 60;
uint32_t hrs = tmp / 60 % 24;
display_buff[0] = display_numbers[min % 10];
display_buff[1] = display_numbers[min / 10 % 10];
display_buff[2] = 0;
display_buff[3] &= BIT(6); // bat
display_buff[4] &= BIT(3); // connect
display_buff[4] |= display_numbers[hrs % 10];
display_buff[5] = display_numbers[hrs / 10 % 10];
}
#endif // USE_CLOCK
extern volatile uint32 osal_sys_tick;
int send_i2c_buf(uint8 addr, uint8 * pdata, int len) {
AP_I2C_TypeDef * pi2cdev = AP_I2C0;
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_TAR = addr;
HAL_ENTER_CRITICAL_SECTION();
pi2cdev->IC_ENABLE = 1;
while(len--) {
pi2cdev->IC_DATA_CMD = *pdata++;
while(!(pi2cdev->IC_RAW_INTR_STAT & 0x10));
}
HAL_EXIT_CRITICAL_SECTION();
uint32 to = osal_sys_tick;
while(1) {
if(pi2cdev->IC_RAW_INTR_STAT & 0x200)// check tx empty
break;
if(osal_sys_tick - to > I2C_WAIT_ms)
return 1;
}
return 0;
}
static void send_to_lcd(uint8_t *pbuf, int len){
init_i2c(0);
//send_i2c_byte(lcd_i2c_addr, 0x48);
send_i2c_buf(lcd_i2c_addr, pbuf, len);
//send_i2c_byte(lcd_i2c_addr, 0x58);
deinit_i2c();
}
void update_lcd(void) {
if (memcmp(&display_out_buff[1], display_buff, sizeof(display_buff))) {
memcpy(&display_out_buff[1], display_buff, sizeof(display_buff));
send_to_lcd(display_out_buff, sizeof(display_out_buff));
}
}
void init_lcd(void) {
init_i2c(0);
send_to_lcd((uint8_t *) lcd_init_cmd, sizeof(lcd_init_cmd)); // sleep: 15.5 uA
// display_out_buff[0] = 0xf0;
// display_out_buff[1] = 0x00;
display_out_buff[3] = 0xFF;
//display_cmp_buff[2+LCD_BUF_SIZE] = 0x58;
//send_i2c_byte(lcd_i2c_addr, 0x58);
deinit_i2c();
}
/****************************************************/

View file

@ -0,0 +1,51 @@
/*
* lcd_th05.h
*
* Created on: 23 янв. 2024 г.
* Author: pvvx
*/
#ifndef _LCD_TH05_H_
#define _LCD_TH05_H_
/*
* TH-05 LCD buffer: byte.bit
--0.4-- --1.4-- --2.4-- BAT
| | | | | | | 3.6
| 0.6 0.0 1.6 1.0 2.6 2.0
| | | | | | | o 3.5
0.3 --0.2-- --1.2-- --2.2-- +--- 3.5
| | | | | | | 3.5|
| 0.5 0.1 1.5 1.1 2.5 2.1 ---- 3.7
| | | | | | | 3.5|
--0.7-- --1.7-- * --2.7-- ---- 2.3
1.3
--4.4-- --5.4--
| | | |
3.0 3.0 4.6 4.0 5.6 5.0
/ \ / \ | | | |
3.4( \_/ 3.2 \_/ )3.4 --4.2-- --5.2--
3.2 / \ 3.2 | | | |
\_/ 4.5 4.1 5.5 5.1 %
3.0 | | | | 5.3
--4.7-- --5.7--
OO 4.3
None: 3.1, 3.3
*/
#define LCD_BUF_SIZE 6
// extern uint8_t lcd_i2c_addr; // LCD controller I2C address
extern uint8_t display_buff[LCD_BUF_SIZE];
void init_lcd(void);
void update_lcd(void);
void show_small_number(int16_t number, bool percent);
void show_big_number_x10(int16_t number);
void show_battery_symbol(bool state);
void show_ble_symbol(bool state);
void show_smiley(uint8_t state);
void show_temp_symbol(uint8_t symbol);
#endif /* _LCD_TH05_H_ */

View file

@ -133,8 +133,8 @@ const ioinit_cfg_t ioInit[] = {
{ GPIO_P32, GPIO_PULL_DOWN },
{ GPIO_P33, GPIO_PULL_DOWN },
{ GPIO_P34, GPIO_PULL_DOWN }
#elif DEVICE == DEVICE_BTH01
{ GPIO_P00, GPIO_PULL_UP }, // Sensor Vdd
#elif (DEVICE == DEVICE_BTH01)
{ GPIO_P00, GPIO_PULL_UP }, // Sensor Vdd
{ GPIO_P01, GPIO_PULL_DOWN },
{ GPIO_P02, GPIO_PULL_DOWN },
{ GPIO_P03, GPIO_PULL_DOWN },
@ -143,7 +143,35 @@ const ioinit_cfg_t ioInit[] = {
{ GPIO_P10, GPIO_PULL_UP }, // RX1
{ GPIO_P11, GPIO_PULL_UP }, // ADC Vbat
{ GPIO_P14, GPIO_PULL_UP }, // KEY
#ifdef GPIO_LED
{ GPIO_P15, GPIO_FLOATING }, // LED
#else
{ GPIO_P15, GPIO_PULL_DOWN },
#endif
{ GPIO_P16, GPIO_PULL_DOWN },
{ GPIO_P17, GPIO_PULL_DOWN },
{ GPIO_P18, GPIO_PULL_UP }, // RX2
{ GPIO_P20, GPIO_PULL_UP }, // TX2
{ GPIO_P23, GPIO_PULL_DOWN },
{ GPIO_P24, GPIO_PULL_DOWN },
{ GPIO_P25, GPIO_PULL_DOWN }, // P25
{ GPIO_P26, GPIO_PULL_DOWN },
// {GPIO_P27, GPIO_FLOATING },
{ GPIO_P31, GPIO_PULL_DOWN },
{ GPIO_P32, GPIO_PULL_DOWN },
{ GPIO_P33, GPIO_FLOATING }, // I2C_SDA
{ GPIO_P34, GPIO_FLOATING } // // I2C_SCL
#elif (DEVICE == DEVICE_TH05)
{ GPIO_P00, GPIO_PULL_UP }, // Sensor Vdd
{ GPIO_P01, GPIO_PULL_DOWN },
{ GPIO_P02, GPIO_PULL_UP },
{ GPIO_P03, GPIO_PULL_DOWN },
{ GPIO_P07, GPIO_PULL_DOWN },
{ GPIO_P09, GPIO_PULL_UP }, // TX1
{ GPIO_P10, GPIO_PULL_UP }, // RX1
{ GPIO_P11, GPIO_PULL_UP }, // ADC Vbat
{ GPIO_P14, GPIO_PULL_UP }, // KEY
{ GPIO_P15, GPIO_PULL_DOWN },
{ GPIO_P16, GPIO_PULL_DOWN },
{ GPIO_P17, GPIO_PULL_DOWN },
{ GPIO_P18, GPIO_PULL_UP }, // RX2
@ -178,11 +206,12 @@ const ioinit_cfg_t ioInit[] = {
for (uint8_t i = 0; i < sizeof(ioInit) / sizeof(ioinit_cfg_t); i++)
hal_gpio_pull_set(ioInit[i].pin, ioInit[i].type);
#if DEVICE == DEVICE_BTH01
hal_gpio_pin_init(GPIO_SPWR, GPIO_OUTPUT);
#ifdef GPIO_SPWR
hal_gpio_write(GPIO_SPWR, 1);
#endif
#ifdef GPIO_LED
hal_gpio_write(GPIO_LED, LED_ON);
#endif
DCDC_CONFIG_SETTING(0x0a);
DCDC_REF_CLK_SETTING(1);
DIG_LDO_CURRENT_SETTING(0x01);
@ -296,8 +325,7 @@ int main(void) {
spif_config(SYS_CLK_DLL_64M, 1, XFRD_FCMD_READ_DUAL, 0, 0);
AP_PCR->CACHE_BYPASS = 1; // just bypass cache
startup_app();
} else
write_reg(OTA_MODE_SELECT_REG, 0);
}// else write_reg(OTA_MODE_SELECT_REG, 0);
#endif
watchdog_config(WDG_2S);

View file

@ -86,7 +86,7 @@ static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simplePro
#if OTA_TYPE
// Simple Profile Characteristic 1 Properties
static CONST uint8_t simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE_NO_RSP | GATT_PROP_NOTIFY; // GATT_PROP_WRITE
static CONST uint8_t simpleProfileChar1Props = GATT_PROP_READ | GATT_PROP_WRITE_NO_RSP | GATT_PROP_NOTIFY;
//static CONST uint8_t simpleProfileChar1UserDesp[] = "OTA\0"; // Simple Profile Characteristic 1 User Description
static gattCharCfg_t simpleProfileChar1Config[GATT_MAX_NUM_CONN]; //
@ -96,7 +96,7 @@ static uint8_t ota_in_len;
#endif
// Simple Profile Characteristic 2 Properties
static CONST uint8_t simpleProfileChar2Props = GATT_PROP_READ | GATT_PROP_WRITE_NO_RSP | GATT_PROP_NOTIFY; // GATT_PROP_WRITE
static CONST uint8_t simpleProfileChar2Props = GATT_PROP_READ | GATT_PROP_WRITE_NO_RSP | GATT_PROP_NOTIFY;
//static CONST uint8_t simpleProfileChar2UserDesp[] = "CMD\0"; // Simple Profile Characteristic 2 User Description
static gattCharCfg_t simpleProfileChar2Config[GATT_MAX_NUM_CONN]; //

View file

@ -15,46 +15,47 @@
/* CHT8310 https://github.com/pvvx/pvvx.github.io/blob/master/THB2/CHT8310.Advanced.Datasheet_Ver1.0.20230407.pdf */
// I2C addres
#define CHT8310_I2C_ADDR0 0x40
#define CHT8310_I2C_ADDR1 0x44
#define CHT8310_I2C_ADDR2 0x48
#define CHT8310_I2C_ADDR3 0x4C
#define CHT8315_I2C_ADDR0 0x40
#define CHT8315_I2C_ADDR1 0x44
#define CHT8315_I2C_ADDR2 0x48
#define CHT8315_I2C_ADDR3 0x4C
// Registers
#define CHT8310_REG_TMP 0x00
#define CHT8310_REG_HMD 0x01
#define CHT8310_REG_STA 0x02
#define CHT8310_REG_CFG 0x03
#define CHT8310_REG_CRT 0x04
#define CHT8310_REG_TLL 0x05
#define CHT8310_REG_TLM 0x06
#define CHT8310_REG_HLL 0x07
#define CHT8310_REG_HLM 0x08
#define CHT8310_REG_OST 0x0f
#define CHT8310_REG_RST 0xfc
#define CHT8310_REG_MID 0xfe
#define CHT8310_REG_VID 0xff
#define CHT8315_REG_TMP 0x00
#define CHT8315_REG_HMD 0x01
#define CHT8315_REG_STA 0x02
#define CHT8315_REG_CFG 0x03
#define CHT8315_REG_CRT 0x04
#define CHT8315_REG_TLL 0x05
#define CHT8315_REG_TLM 0x06
#define CHT8315_REG_HLL 0x07
#define CHT8315_REG_HLM 0x08
#define CHT8315_REG_OST 0x0f
#define CHT8315_REG_RST 0xfc
#define CHT8315_REG_MID 0xfe
#define CHT8315_REG_VID 0xff
// Status register mask
#define CHT8310_STA_BUSY 0x8000
#define CHT8310_STA_THI 0x4000
#define CHT8310_STA_TLO 0x2000
#define CHT8310_STA_HHI 0x1000
#define CHT8310_STA_HLO 0x0800
#define CHT8315_STA_BUSY 0x8000
#define CHT8315_STA_THI 0x4000
#define CHT8315_STA_TLO 0x2000
#define CHT8315_STA_HHI 0x1000
#define CHT8315_STA_HLO 0x0800
// Config register mask
#define CHT8310_CFG_MASK 0x8000
#define CHT8310_CFG_SD 0x4000
#define CHT8310_CFG_ALTH 0x2000
#define CHT8310_CFG_EM 0x1000
#define CHT8310_CFG_EHT 0x0100
#define CHT8310_CFG_TME 0x0080
#define CHT8310_CFG_POL 0x0020
#define CHT8310_CFG_ALT 0x0018
#define CHT8310_CFG_CONSEC_FQ 0x0006
#define CHT8310_CFG_ATM 0x0001
#define CHT8315_CFG_MASK 0x8000
#define CHT8315_CFG_SD 0x4000
#define CHT8315_CFG_ALTH 0x2000
#define CHT8315_CFG_EM 0x1000
#define CHT8315_CFG_EHT 0x0100
#define CHT8315_CFG_TME 0x0080
#define CHT8315_CFG_POL 0x0020
#define CHT8315_CFG_ALT 0x0018
#define CHT8315_CFG_CONSEC_FQ 0x0006
#define CHT8315_CFG_ATM 0x0001
#define CHT8310_ID 0x5959
#define CHT83xx_MID 0x5959
#define CHT8315_VID 0x8315
/* CHT8305 https://github.com/pvvx/pvvx.github.io/blob/master/BTH01/CHT8305.pdf */
@ -107,17 +108,17 @@ struct __attribute__((packed)) _cht8305_config_t{
} cht8305_config_t;
*/
#define CHT8305_ID 0x5959
#define CHT8305_VID 0x8305
/*---------------------------------------
Датчик влажности AHT25
---------------------------------------*/
#define AHT30_I2C_ADDR 0x38
#define AHT2x_I2C_ADDR 0x38
#define AHT30_CMD_INI 0x0E1 // Initialization Command
#define AHT30_CMD_TMS 0x0AC // Trigger Measurement Command
#define AHT30_DATA_TMS 0x3300 // Trigger Measurement data
#define AHT30_CMD_RST 0x0BA // Soft Reset Command
#define AHT2x_CMD_INI 0x0E1 // Initialization Command
#define AHT2x_CMD_TMS 0x0AC // Trigger Measurement Command
#define AHT2x_DATA_TMS 0x3300 // Trigger Measurement data
#define AHT2x_CMD_RST 0x0BA // Soft Reset Command
typedef struct _measured_data_t {
@ -137,25 +138,27 @@ typedef struct _thsensor_coef_t {
int16_t humi_z;
} thsensor_coef_t;
extern const thsensor_coef_t def_thcoef;
#if DEVICE == DEVICE_BTH01
extern const thsensor_coef_t def_thcoef_aht30;
#endif
typedef int (*psernsor_rd_t)(void);
//typedef void (*psernsor_sm_t)(void);
typedef struct _thsensor_cfg_t {
thsensor_coef_t coef;
uint16_t mid;
uint16_t vid;
uint8_t i2c_addr;
psernsor_rd_t read_sensor;
// psernsor_sm_t start_measure;
} thsensor_cfg_t;
extern thsensor_cfg_t thsensor_cfg;
#define thsensor_cfg_size (sizeof(thsensor_cfg)-3)
#define thsensor_cfg_send_size 19
void init_sensor(void);
void start_measure(void);
int read_sensor(void);
//void init_i2c(void);
//void deinit_i2c(void);
void init_i2c(bool speed400khz);
void deinit_i2c(void);
int send_i2c_byte(uint8 addr, uint8 data);
#endif // _SENSORS_H_

View file

@ -38,7 +38,7 @@ const thsensor_coef_t def_thcoef_aht30 = {
.humi_z = 0
};
void init_i2c(void) {
void init_i2c(bool speed400khz) {
hal_gpio_fmux_set(I2C_SCL, FMUX_IIC0_SCL);
hal_gpio_fmux_set(I2C_SDA, FMUX_IIC0_SDA);
@ -50,45 +50,45 @@ void init_i2c(void) {
hal_clk_gate_enable(MOD_I2C0);
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_CON = 0x61;
#if SET_I2C_SPEED == 100
pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x01 << 1); // SPEED_STANDARD
if (pclk == 16000000) {
pi2cdev->IC_SS_SCL_HCNT = 70; //16
pi2cdev->IC_SS_SCL_LCNT = 76; //32)
} else if (pclk == 32000000) {
pi2cdev->IC_SS_SCL_HCNT = 148; //16
pi2cdev->IC_SS_SCL_LCNT = 154; //32)
} else if (pclk == 48000000) {
pi2cdev->IC_SS_SCL_HCNT = 230; //16
pi2cdev->IC_SS_SCL_LCNT = 236; //32)
} else if (pclk == 64000000) {
pi2cdev->IC_SS_SCL_HCNT = 307; //16
pi2cdev->IC_SS_SCL_LCNT = 320; //32)
} else if (pclk == 96000000) {
pi2cdev->IC_SS_SCL_HCNT = 460; //16
pi2cdev->IC_SS_SCL_LCNT = 470; //32)
if(speed400khz) {
// SET_I2C_SPEED 400 kHz
pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x02 << 1); // SPEED_FAST
if (pclk == 16000000) {
pi2cdev->IC_FS_SCL_HCNT = 10;
pi2cdev->IC_FS_SCL_LCNT = 17;
} else if (pclk == 32000000) {
pi2cdev->IC_FS_SCL_HCNT = 30;
pi2cdev->IC_FS_SCL_LCNT = 35;
} else if (pclk == 48000000) {
pi2cdev->IC_FS_SCL_HCNT = 48;
pi2cdev->IC_FS_SCL_LCNT = 54;
} else if (pclk == 64000000) {
pi2cdev->IC_FS_SCL_HCNT = 67;
pi2cdev->IC_FS_SCL_LCNT = 75;
} else if (pclk == 96000000) {
pi2cdev->IC_FS_SCL_HCNT = 105;
pi2cdev->IC_FS_SCL_LCNT = 113;
}
} else {
// SET_I2C_SPEED 100 kHz
pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x01 << 1); // SPEED_STANDARD
if (pclk == 16000000) {
pi2cdev->IC_SS_SCL_HCNT = 70; //16
pi2cdev->IC_SS_SCL_LCNT = 76; //32)
} else if (pclk == 32000000) {
pi2cdev->IC_SS_SCL_HCNT = 148; //16
pi2cdev->IC_SS_SCL_LCNT = 154; //32)
} else if (pclk == 48000000) {
pi2cdev->IC_SS_SCL_HCNT = 230; //16
pi2cdev->IC_SS_SCL_LCNT = 236; //32)
} else if (pclk == 64000000) {
pi2cdev->IC_SS_SCL_HCNT = 307; //16
pi2cdev->IC_SS_SCL_LCNT = 320; //32)
} else if (pclk == 96000000) {
pi2cdev->IC_SS_SCL_HCNT = 460; //16
pi2cdev->IC_SS_SCL_LCNT = 470; //32)
}
}
#elif SET_I2C_SPEED == 400
pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x02 << 1); // SPEED_FAST
if (pclk == 16000000) {
pi2cdev->IC_FS_SCL_HCNT = 10;
pi2cdev->IC_FS_SCL_LCNT = 17;
} else if (pclk == 32000000) {
pi2cdev->IC_FS_SCL_HCNT = 30;
pi2cdev->IC_FS_SCL_LCNT = 35;
} else if (pclk == 48000000) {
pi2cdev->IC_FS_SCL_HCNT = 48;
pi2cdev->IC_FS_SCL_LCNT = 54;
} else if (pclk == 64000000) {
pi2cdev->IC_FS_SCL_HCNT = 67;
pi2cdev->IC_FS_SCL_LCNT = 75;
} else if (pclk == 96000000) {
pi2cdev->IC_FS_SCL_HCNT = 105;
pi2cdev->IC_FS_SCL_LCNT = 113;
}
#else
#error SET_I2C_SPEED = ?
#endif
// pi2cdev->IC_TAR = I2C_MASTER_ADDR_DEF;
pi2cdev->IC_INTR_MASK = 0;
pi2cdev->IC_RX_TL = 0x0;
@ -205,119 +205,119 @@ int send_i2c_wreg(uint8 addr, uint8 reg, uint16 data) {
return 0;
}
__ATTR_SECTION_XIP__ void init_sensor(void) {
init_i2c();
#if DEVICE == DEVICE_THB2
send_i2c_byte(0, 0x06); // Reset command using the general call address
WaitMs(SENSOR_RESET_TIMEOUT_ms);
thsensor_cfg.i2c_addr = CHT8310_I2C_ADDR0;
if(!read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_MID, (uint8 *)&thsensor_cfg.mid, 2) // 0x5959
&& !read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_VID, (uint8 *)&thsensor_cfg.vid, 2)) { // 0x8215
if(adv_wrk.measure_interval_ms >= 5000) // > 5 sec
send_i2c_wreg(CHT8310_I2C_ADDR0, CHT8310_REG_CRT, 0x0300); // Set conversion ratio 5 sec
// else 1 sec
if(!thsensor_cfg.coef.temp_k) {
osal_memcpy(&thsensor_cfg.coef, &def_thcoef_cht8310, sizeof(thsensor_cfg.coef));
}
} else
thsensor_cfg.i2c_addr = 0;
#elif DEVICE == DEVICE_BTH01
#define USE_DEFAULT_SETS_SENSOR 0 // for CHT8305
#if USE_DEFAULT_SETS_SENSOR
hal_gpio_write(GPIO_SPWR, 0);
WaitMs(SENSOR_POWER_TIMEOUT_ms);
hal_gpio_write(GPIO_SPWR, 1);
#endif
thsensor_cfg.i2c_addr = CHT8305_I2C_ADDR0;
if((!read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_MID, (uint8 *)&thsensor_cfg.mid, 2)) // 0x5959
&& (!read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_VID, (uint8 *)&thsensor_cfg.vid, 2))) { // 0x8305
#if !USE_DEFAULT_SETS_SENSOR
// Soft reset command
send_i2c_wreg(thsensor_cfg.i2c_addr, CHT8305_REG_CFG,
CHT8305_CFG_SOFT_RESET | CHT8305_CFG_MODE);
WaitMs(SENSOR_RESET_TIMEOUT_ms);
// Configure
send_i2c_wreg(thsensor_cfg.i2c_addr, CHT8305_REG_CFG, CHT8305_CFG_MODE );
#endif
// WaitMs(SENSOR_MEASURING_TIMEOUT_ms);
send_i2c_byte(thsensor_cfg.i2c_addr, CHT8305_REG_TMP); // start measure T/H
if(!thsensor_cfg.coef.temp_k) {
osal_memcpy(&thsensor_cfg.coef, &def_thcoef_cht8305, sizeof(thsensor_cfg.coef));
}
} else {
thsensor_cfg.i2c_addr = AHT30_I2C_ADDR;
if(send_i2c_wreg(thsensor_cfg.i2c_addr, AHT30_CMD_TMS, AHT30_DATA_TMS))
thsensor_cfg.i2c_addr = 0;
else
if(!thsensor_cfg.coef.temp_k) {
osal_memcpy(&thsensor_cfg.coef, &def_thcoef_aht30, sizeof(thsensor_cfg.coef));
}
}
#endif // DEVICE == DEVICE_BTH01
int read_sensor_cht83xx(void) {
uint8 reg_data[4];
int32 _r32;
int16 _r16;
init_i2c(1);
_r32 = read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8315_REG_TMP, reg_data, 2);
//? WaitUs(100);
_r32 |= read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8315_REG_HMD, &reg_data[2], 2);
deinit_i2c();
if (!_r32) {
_r16 = (reg_data[0] << 8) | reg_data[1];
measured_data.temp = ((int32)(_r16 * thsensor_cfg.coef.temp_k) >> 16) + thsensor_cfg.coef.temp_z;; // x 0.01 C
_r32 = ((reg_data[2] << 8) | reg_data[3]) & 0x7fff;
measured_data.humi = ((uint32)(_r32 * thsensor_cfg.coef.humi_k) >> 16) + thsensor_cfg.coef.humi_z; // x 0.01 %
if (measured_data.humi < 0)
measured_data.humi = 0;
else if (measured_data.humi > 9999)
measured_data.humi = 9999;
measured_data.count++;
return 0;
}
return 1;
}
int read_sensor_ahtxx(void) {
uint32_t _temp;
uint8 reg_data[8];
init_i2c(1);
if(!read_noreg_i2c_bytes(thsensor_cfg.i2c_addr, reg_data, 7)
&& (reg_data[0] & 0x80) == 0) { // busy
deinit_i2c();
_temp = ((reg_data[3] & 0x0F) << 16) | (reg_data[4] << 8) | reg_data[5];
measured_data.temp = ((uint32_t)(_temp * thsensor_cfg.coef.temp_k) >> 16) + thsensor_cfg.coef.temp_z; // x 0.01 C
_temp = (reg_data[1] << 12) | (reg_data[2] << 4) | (reg_data[3] >> 4);
measured_data.humi = ((uint32_t)(_temp * thsensor_cfg.coef.humi_k) >> 16) + thsensor_cfg.coef.humi_z; // x 0.01 %
if (measured_data.humi < 0)
measured_data.humi = 0;
else if (measured_data.humi > 9999)
measured_data.humi = 9999;
return 0;
}
deinit_i2c();
return 1;
}
int read_sensor(void) {
int ret = 1;
if(thsensor_cfg.i2c_addr && thsensor_cfg.read_sensor != NULL)
ret = thsensor_cfg.read_sensor();
if(ret)
init_sensor();
return ret;
}
void start_measure(void) {
if(thsensor_cfg.i2c_addr) {
init_i2c();
#if DEVICE == DEVICE_THB2
uint8 reg_data[4];
int32 _r32;
int16 _r16;
_r32 = read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_TMP, reg_data, 2);
//? WaitUs(100);
_r32 |= read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8310_REG_HMD, &reg_data[2], 2);
deinit_i2c();
if (!_r32) {
_r16 = (reg_data[0] << 8) | reg_data[1];
measured_data.temp = ((int32)(_r16 * thsensor_cfg.coef.temp_k) >> 16) + thsensor_cfg.coef.temp_z;; // x 0.01 C
_r32 = ((reg_data[2] << 8) | reg_data[3]) & 0x7fff;
measured_data.humi = ((uint32)(_r32 * thsensor_cfg.coef.humi_k) >> 16) + thsensor_cfg.coef.humi_z; // x 0.01 %
if (measured_data.humi < 0)
measured_data.humi = 0;
else if (measured_data.humi > 9999)
measured_data.humi = 9999;
measured_data.count++;
return 0;
if(thsensor_cfg.i2c_addr == AHT2x_I2C_ADDR) {
init_i2c(1);
send_i2c_wreg(thsensor_cfg.i2c_addr, AHT2x_CMD_TMS, AHT2x_DATA_TMS);
deinit_i2c();
}
#elif DEVICE == DEVICE_BTH01
uint8 reg_data[8];
if(thsensor_cfg.i2c_addr == AHT30_I2C_ADDR) {
if(!read_noreg_i2c_bytes(thsensor_cfg.i2c_addr, reg_data, 7)
&& (reg_data[0] & 0x80) == 0) { // busy
send_i2c_wreg(thsensor_cfg.i2c_addr, AHT30_CMD_TMS, AHT30_DATA_TMS);
deinit_i2c();
uint32_t _temp;
_temp = ((reg_data[3] & 0x0F) << 16) | (reg_data[4] << 8) | reg_data[5];
measured_data.temp = ((uint32_t)(_temp * thsensor_cfg.coef.temp_k) >> 16) + thsensor_cfg.coef.temp_z; // x 0.01 C
_temp = (reg_data[1] << 12) | (reg_data[2] << 4) | (reg_data[3] >> 4);
measured_data.humi = ((uint32_t)(_temp * thsensor_cfg.coef.humi_k) >> 16) + thsensor_cfg.coef.humi_z; // x 0.01 %
if (measured_data.humi < 0)
measured_data.humi = 0;
else if (measured_data.humi > 9999)
measured_data.humi = 9999;
return 0;
}
} else if(!read_noreg_i2c_bytes(thsensor_cfg.i2c_addr, reg_data, 4)) {
else if(thsensor_cfg.i2c_addr == CHT8305_I2C_ADDR0) {
init_i2c(1);
send_i2c_byte(thsensor_cfg.i2c_addr, CHT8305_REG_TMP); // start measure T/H
deinit_i2c();
uint16_t _temp;
_temp = (reg_data[0] << 8) | reg_data[1];
measured_data.temp = ((uint32_t)(_temp * thsensor_cfg.coef.temp_k) >> 16) + thsensor_cfg.coef.temp_z; // x 0.01 C
_temp = (reg_data[2] << 8) | reg_data[3];
measured_data.humi = ((uint32_t)(_temp * thsensor_cfg.coef.humi_k) >> 16) + thsensor_cfg.coef.humi_z; // x 0.01 %
if (measured_data.humi < 0)
measured_data.humi = 0;
else if (measured_data.humi > 9999)
measured_data.humi = 9999;
return 0;
}
#else
#error "DEVICE Not released!"
#endif
}
init_sensor();
return 1;
}
__ATTR_SECTION_XIP__ void init_sensor(void) {
uint8_t *ptabinit = NULL;
thsensor_cfg.read_sensor = NULL;
init_i2c(1);
thsensor_cfg.i2c_addr = CHT8315_I2C_ADDR0;
if(!read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8315_REG_MID, (uint8 *)&thsensor_cfg.mid, 2) // 0x5959
&& !read_i2c_bytes(thsensor_cfg.i2c_addr, CHT8315_REG_VID, (uint8 *)&thsensor_cfg.vid, 2)) { // 0x8215
if(thsensor_cfg.mid == CHT83xx_MID) {
if(thsensor_cfg.vid == CHT8305_VID) {
ptabinit = (uint8_t *)&def_thcoef_cht8305;
thsensor_cfg.read_sensor = read_sensor_cht83xx;
} else if(thsensor_cfg.vid == CHT8315_VID) { // 0x8310/0x8315 ?
/* #if USE_DEFAULT_SETS_SENSOR
hal_gpio_write(GPIO_SPWR, 0);
WaitMs(SENSOR_POWER_TIMEOUT_ms);
hal_gpio_write(GPIO_SPWR, 1);
#else
// Soft reset command
send_i2c_wreg(thsensor_cfg.i2c_addr, CHT8305_REG_CFG,
CHT8305_CFG_SOFT_RESET | CHT8305_CFG_MODE);
WaitMs(SENSOR_RESET_TIMEOUT_ms);
// Configure
send_i2c_wreg(thsensor_cfg.i2c_addr, CHT8305_REG_CFG, CHT8305_CFG_MODE );
#endif */
if(adv_wrk.measure_interval_ms >= 5000) // > 5 sec
send_i2c_wreg(CHT8315_I2C_ADDR0, CHT8315_REG_CRT, 0x0300); // Set conversion ratio 5 sec
// else 1 sec
thsensor_cfg.read_sensor = read_sensor_cht83xx;
ptabinit = (uint8_t *)&def_thcoef_cht8310;
}
} else
thsensor_cfg.i2c_addr = 0;
} else {
thsensor_cfg.i2c_addr = AHT2x_I2C_ADDR;
if(!send_i2c_wreg(thsensor_cfg.i2c_addr, AHT2x_CMD_TMS, AHT2x_DATA_TMS)) {
ptabinit = (uint8_t *)&def_thcoef_aht30;
thsensor_cfg.read_sensor = read_sensor_ahtxx;
} else
thsensor_cfg.i2c_addr = 0;
}
if(thsensor_cfg.coef.temp_k == 0 && ptabinit) {
osal_memcpy(&thsensor_cfg.coef, ptabinit, sizeof(thsensor_cfg.coef));
}
deinit_i2c();
}

View file

@ -1,12 +1,12 @@
/**************************************************************************************************
/*******************************************************************************
Filename: simpleBLEPeripheral.c
Revised:
Revision:
Description: This file contains the Simple BLE Peripheral sample application
Description: This file contains the Simple BLE Peripheral sample application
**************************************************************************************************/
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
@ -41,6 +41,7 @@
#include "sensor.h"
#include "battery.h"
#include "sbp_profile.h"
#include "lcd_th05.h"
/*********************************************************************
* MACROS
*/
@ -98,7 +99,20 @@ static gaprole_States_t gapProfileState = GAPROLE_INIT;
static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg );
static void peripheralStateNotificationCB( gaprole_States_t newState );
//static void simpleProfileChangeCB( uint8 paramID );
static void peripheralStateReadRssiCB( int8 rssi );
static void peripheralStateReadRssiCB( int8 rssi );
#if (DEV_SERVICES & SERVICE_SCREEN)
void chow_measure(void) {
show_big_number_x10(measured_data.temp/10);
show_small_number(measured_data.humi/100, true);
show_battery_symbol(measured_data.battery < 20);
show_temp_symbol(3);
show_smiley(0);
show_ble_symbol(gapRole_state == GAPROLE_CONNECTED);
update_lcd();
}
#endif
const char* hex_ascii = { "0123456789ABCDEF" };
uint8_t * str_bin2hex(uint8_t *d, uint8_t *s, int len) {
@ -180,15 +194,22 @@ static void set_adv_interval(uint16 advInt)
#endif
}
//extern void start_measure(void);
static void adv_measure(void) {
if(gapRole_AdvEnabled) {
if(++adv_wrk.adv_count >= cfg.measure_interval) {
if(adv_wrk.adv_count == (uint8_t)(cfg.measure_interval - 1)) {
start_measure();
} else if(adv_wrk.adv_count >= cfg.measure_interval) {
adv_wrk.adv_count = 0;
read_sensor();
if(++adv_wrk.adv_batt_count >= cfg.batt_interval) { // = 60
adv_wrk.adv_batt_count = 0;
batt_start_measure();
}
#if (DEV_SERVICES & SERVICE_SCREEN)
chow_measure();
#endif
bthome_data_beacon((padv_bthome_ns1_t) gapRole_AdvertData);
LL_SetAdvData(sizeof(adv_bthome_ns1_t), gapRole_AdvertData);
}
@ -197,6 +218,7 @@ static void adv_measure(void) {
set_new_adv_interval(cfg.advertising_interval * 100);
}
}
adv_wrk.adv_count++;
}
}
@ -208,10 +230,12 @@ static void posedge_int_wakeup_cb(GPIO_Pin_e pin, IO_Wakeup_Pol_e type)
(void) pin;
if(type == POSEDGE)
{
adv_wrk.adv_con_count = 30000/DEF_CON_ADV_INERVAL_MS; // 60 sec
LOG("int or wakeup(pos):gpio:%d type:%d\n", pin, type);
#ifdef GPIO_LED
hal_gpio_write(GPIO_LED, LED_OFF);
#endif
if(gapRole_AdvEnabled) {
adv_wrk.adv_con_count = 60000/DEF_CON_ADV_INERVAL_MS; // 60 sec
set_new_adv_interval(DEF_CON_ADV_INERVAL); // actual time = advInt * 625us
}
}
@ -227,7 +251,9 @@ static void negedge_int_wakeup_cb(GPIO_Pin_e pin, IO_Wakeup_Pol_e type)
if(type == NEGEDGE)
{
LOG("int or wakeup(neg):gpio:%d type:%d\n", pin, type);
#ifdef GPIO_LED
hal_gpio_write(GPIO_LED, LED_ON);
#endif
}
else
{
@ -237,12 +263,20 @@ static void negedge_int_wakeup_cb(GPIO_Pin_e pin, IO_Wakeup_Pol_e type)
void init_led_key(void)
{
#ifdef GPIO_KEY
hal_gpioin_register(GPIO_KEY, posedge_int_wakeup_cb, negedge_int_wakeup_cb);
hal_gpioretention_register(GPIO_LED);//enable this pin retention
#endif
#ifdef GPIO_LED
hal_gpio_write(GPIO_LED, LED_ON);
#if DEVICE == DEVICE_BTH01
hal_gpioretention_register(GPIO_SPWR);//enable this pin retention
hal_gpioretention_register(GPIO_LED);//enable this pin retention
#endif
#ifdef GPIO_LPWR // питание LCD драйвера
hal_gpio_write(GPIO_LPWR, 1);
hal_gpioretention_register(GPIO_LPWR);//enable this pin retention
#endif
#ifdef GPIO_SPWR // питание сенсора CHT8305_VDD
hal_gpio_write(GPIO_SPWR, 1);
hal_gpioretention_register(GPIO_SPWR);//enable this pin retention
#endif
}
@ -316,6 +350,10 @@ void SimpleBLEPeripheral_Init( uint8 task_id )
init_led_key();
#if (DEV_SERVICES & SERVICE_SCREEN)
init_lcd();
#endif
init_sensor();
set_serial_number();
@ -355,6 +393,13 @@ void SimpleBLEPeripheral_Init( uint8 task_id )
GGS_SetParameter( GGS_DEVICE_NAME_ATT, gapRole_ScanRspData[0] - 1, (void *)&gapRole_ScanRspData[2] ); // GAP_DEVICE_NAME_LEN, attDeviceName );
// Set advertising interval
#if defined(OTA_TYPE) && OTA_TYPE == OTA_TYPE_BOOT
if (read_reg(OTA_MODE_SELECT_REG) == 0x55) {
write_reg(OTA_MODE_SELECT_REG, 0);
adv_wrk.adv_con_count = 60000/DEF_OTA_ADV_INERVAL_MS; // 60 sec
set_new_adv_interval(DEF_CON_ADV_INERVAL); // actual time = advInt * 625us
} else
#endif
set_adv_interval(DEF_ADV_INERVAL); // actual time = advInt * 625us
HCI_PPLUS_AdvEventDoneNoticeCmd(simpleBLEPeripheral_TaskID, ADV_BROADCAST_EVT);
@ -379,13 +424,8 @@ void SimpleBLEPeripheral_Init( uint8 task_id )
DevInfo_AddService(); // Device Information Service
Batt_AddService();
TH_AddService();
//Batt_Register(NULL);
SimpleProfile_AddService( GATT_ALL_SERVICES ); // Simple GATT Profile
//uint8 OTA_Passward_AscII[8] = {'1','2','3','4','5','6','7','8'};
//ota_app_AddService_UseKey(8, OTA_Passward_AscII);
// ota_app_AddService();
#if (1)
#if 0 // CODED PHY not work?
deviceFeatureSet.featureSet[1] |= (uint8)(
@ -411,9 +451,11 @@ void SimpleBLEPeripheral_Init( uint8 task_id )
#endif
// Setup a delayed profile startup
osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
// for receive HCI complete message
GAP_RegisterForHCIMsgs(simpleBLEPeripheral_TaskID);
LL_PLUS_PerStats_Init(&g_perStatsByChanTest);
batt_start_measure();
LOG("=====SimpleBLEPeripheral_Init Done=======\n");
@ -471,6 +513,10 @@ uint16 BLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
{
LOG("TIMER_EVT\n");
read_sensor();
start_measure();
#if (DEV_SERVICES & SERVICE_SCREEN)
chow_measure();
#endif
// TH Notify
TH_NotifyLevel();
if(++adv_wrk.adv_batt_count >= cfg.batt_interval) { // 60 sec
@ -499,7 +545,14 @@ uint16 BLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
#endif
HCI_LE_ReadResolvingListSizeCmd();
#ifdef GPIO_LED
hal_gpio_write(GPIO_LED, LED_OFF);
#endif
//adv_wrk.adv_count = 0;
#if (DEV_SERVICES & SERVICE_SCREEN)
show_big_number_x10(APP_VERSION);
update_lcd();
#endif
// return unprocessed events
return ( events ^ SBP_START_DEVICE_EVT );
}
@ -604,6 +657,10 @@ static void peripheralStateReadRssiCB( int8 rssi )
osal_start_reload_timer(simpleBLEPeripheral_TaskID, TIMER_BATT_EVT, adv_wrk.measure_interval_ms); // 10000 ms
HCI_PPLUS_ConnEventDoneNoticeCmd(simpleBLEPeripheral_TaskID, NULL);
LOG("Gaprole_Connected\n");
#if (DEV_SERVICES & SERVICE_SCREEN)
show_ble_symbol(1);
update_lcd();
#endif
break;
case GAPROLE_CONNECTED_ADV:
@ -615,6 +672,10 @@ static void peripheralStateReadRssiCB( int8 rssi )
adv_wrk.adv_con_count = 1;
osal_stop_timerEx(simpleBLEPeripheral_TaskID, TIMER_BATT_EVT);
adv_wrk.adv_count = 0;
#if (DEV_SERVICES & SERVICE_SCREEN)
show_ble_symbol(0);
update_lcd();
#endif
break;
case GAPROLE_WAITING_AFTER_TIMEOUT:
@ -631,6 +692,6 @@ static void peripheralStateReadRssiCB( int8 rssi )
gapProfileState = newState;
LOG("[GAP ROLE %d]\n",newState);
VOID gapProfileState;
// VOID gapProfileState;
}