v2.0 beta3
This commit is contained in:
parent
b6b3ea746e
commit
7238ae7e11
46 changed files with 18735 additions and 18423 deletions
22
README-ru.md
22
README-ru.md
|
|
@ -11,6 +11,11 @@
|
|||
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
|  |  |  |  |  |  | 
|
||||
|
||||
| [KEY2](https://pvvx.github.io/iSearching) |
|
||||
|:---:|
|
||||
|  и другим программным обеспечением, работающим в формате [BTHome](https://bthome.io/).
|
||||
|
||||
Все прошивки поддерживают любой из датчиков: [CHT8215](pvvx.github.io/THB2/CHT8315%20Advanced%20Datasheet%20Ver1.6%2020230927.pdf) ([CHT8310](https://pvvx.github.io/THB2/CHT8310%20Advanced%20Datasheet%20Ver1.1%2020230927.pdf)), [CHT8305](https://github.com/pvvx/pvvx.github.io/blob/master/THB2/CHT8305C%20Advanced%20Datasheet%20Ver2.5%202021-10-26.pdf), [CHT832x](pvvx.github.io/THB2/CHT832X%20Advanced%20Datasheet%20Ver1.pdf), AHT20..30.
|
||||
|
|
@ -34,13 +39,14 @@ _Далее, с помощью соединения BLE в [PHY62x2BTHome.html](
|
|||
|
||||
| Устройство | Файл Boot | Файл OTA | Маркировка на печатной плате |
|
||||
|:---:|:---:|:---:|:---:|
|
||||
| [THB1](https://pvvx.github.io/THB1) | BOOT_THB1_v19.hex | THB1_v19.bin | нет |
|
||||
| [THB2](https://pvvx.github.io/THB2) | BOOT_THB2_v19.hex | THB2_v19.bin | нет |
|
||||
| [THB3](https://pvvx.github.io/THB3) | BOOT_THB2_v19.hex | THB2_v19.bin | нет |
|
||||
| [BTH01](https://pvvx.github.io/BTH01) | BOOT_BTH01_v19.hex | BTH01_v19.bin | нет |
|
||||
| [TH05_V1.4](https://pvvx.github.io/TH-05) | BOOT_TH05_v19.hex | TH05_v19.bin | TH05_V1.4, TH05_V1.5, TH05_V1.6 с чипом BL55028 |
|
||||
| [TH05_V1.3](https://pvvx.github.io/TH05-v1.3) | BOOT_TH05D_v19.hex | TH05D_v19.bin | RSH-TH05-V1.3 с чипом BL55072 |
|
||||
| [TH05F](https://pvvx.github.io/TH05F) | BOOT_TH05F_v19.hex | TH05F_v19.bin | TH05Y_V1.1, TH05Y_V1.2, TH05Y_V3.1 с чипом QD01 2332 NT |
|
||||
| [THB1](https://pvvx.github.io/THB1) | BOOT_THB1_v20.hex | THB1_v20.bin | нет |
|
||||
| [THB2](https://pvvx.github.io/THB2) | BOOT_THB2_v20.hex | THB2_v20.bin | нет |
|
||||
| [THB3](https://pvvx.github.io/THB3) | BOOT_THB2_v20.hex | THB2_v20.bin | нет |
|
||||
| [BTH01](https://pvvx.github.io/BTH01) | BOOT_BTH01_v20.hex | BTH01_v20.bin | нет |
|
||||
| [TH05_V1.4](https://pvvx.github.io/TH-05) | BOOT_TH05_v20.hex | TH05_v20.bin | TH05_V1.4, TH05_V1.5, TH05_V1.6 с чипом BL55028 |
|
||||
| [TH05_V1.3](https://pvvx.github.io/TH05-v1.3) | BOOT_TH05D_v20.hex | TH05D_v20.bin | RSH-TH05-V1.3 с чипом BL55072 |
|
||||
| [TH05F](https://pvvx.github.io/TH05F) | BOOT_TH05F_v20.hex | TH05F_v20.bin | TH05Y_V1.1, TH05Y_V1.2, TH05Y_V3.1 с чипом QD01 2332 NT |
|
||||
| [KEY2](https://pvvx.github.io/iSearching) | BOOT_KEY2_v20.hex | KEY2_v20.bin | SoC ST17H66B |
|
||||
|
||||
Основные файлы прошивок, BOOT_xxx_vxx.hex для программирования через USB-COM адаптер и xxx_vxx.bin для OTA, находятся в директории [bin](https://github.com/pvvx/THB2/tree/master/bin).
|
||||
|
||||
|
|
@ -94,7 +100,7 @@ LCD имеет разную разводку сегментов в зависи
|
|||
| 1.7 | <ul><li>Исправление ошибки (> 42 C) для сенсора CHT8305</li></ul> |
|
||||
| 1.8 | <ul><li>Добавлено отображение температуры в градусах Фаренгейта</li></ul> |
|
||||
| 1.9 | <ul><li>Исправлена ошибка восстановления измененного имени устройства после сброса питания</li></ul> |
|
||||
| 2.0beta2 | <ul><li>Добавлена обработка датчика CHT832x (поддержка платы TH05Y_v3.1)</li><li>Исправление ошибки в bin-файлах BOOT OTA</li><li>Добавлена функция сна при полном разряде батареи.</li><li>Добавлена опытная прошивка для брелков [iSearching](https://pvvx.github.io/iSearching) на чипе ST17H66B</li></ul> |
|
||||
| 2.0beta3 | <ul><li>Добавлена обработка датчика CHT832x (поддержка платы TH05Y_v3.1)</li><li>Исправление ошибки в bin-файлах BOOT OTA</li><li>Добавлена функция сна при полном разряде батареи.</li><li>Добавлена опытная прошивка для брелков [iSearching](https://pvvx.github.io/iSearching) на чипе ST17H66B с поддержкой FindMy</li></ul> |
|
||||
|
||||
## Прошивка
|
||||
|
||||
|
|
|
|||
26
README.md
26
README.md
|
|
@ -1,7 +1,7 @@
|
|||
[](README.md)
|
||||
[](README-ru.md)
|
||||
|
||||
# BTHome THB1, THB2, THB3, BTH01, TH05 (HW: v1.3..1.6), TH05F
|
||||
# BTHome THB1, THB2, THB3, BTH01, TH05 (HW: v1.3..1.6), TH05F, iSearching
|
||||
|
||||
Custom firmware for Tuya devices based on the PHY622x2 chipset.
|
||||
|
||||
|
|
@ -11,6 +11,12 @@ Custom firmware for Tuya devices based on the PHY622x2 chipset.
|
|||
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
|  |  |  |  |  |  | 
|
||||
|
||||
| [KEY2](https://pvvx.github.io/iSearching) |
|
||||
|:---:|
|
||||
|  and other software running in the [BTHome](https://bthome.io/) format.
|
||||
|
||||
All firmware supports any of these sensors: [CHT8215](pvvx.github.io/THB2/CHT8315%20Advanced%20Datasheet%20Ver1.6%2020230927.pdf) ([CHT8310](https://pvvx.github.io/THB2/CHT8310%20Advanced%20Datasheet%20Ver1.1%2020230927.pdf)), [CHT8305](https://github.com/pvvx/pvvx.github.io/blob/master/THB2/CHT8305C%20Advanced%20Datasheet%20Ver2.5%202021-10-26.pdf), [CHT832x](pvvx.github.io/THB2/CHT832X%20Advanced%20Datasheet%20Ver1.pdf), AHT20..30.
|
||||
|
|
@ -35,13 +41,15 @@ The [Boot](#fw-boot-and-ota) firmware has minimal functions. `FW Boot` is only u
|
|||
|
||||
| Device | Boot file | OTA file | Printed circuit board labelling |
|
||||
|:---:|:---:|:---:|:---:|
|
||||
| [THB1](https://pvvx.github.io/THB1) | BOOT_THB1_v19.hex | THB1_v19.bin | no |
|
||||
| [THB2](https://pvvx.github.io/THB2) | BOOT_THB2_v19.hex | THB2_v19.bin | no |
|
||||
| [THB3](https://pvvx.github.io/THB3) | BOOT_THB2_v19.hex | THB2_v19.bin | no |
|
||||
| [BTH01](https://pvvx.github.io/BTH01) | BOOT_BTH01_v19.hex | BTH01_v19.bin | no |
|
||||
| [TH05_V1.4](https://pvvx.github.io/TH-05) | BOOT_TH05_v19.hex | TH05_v19.bin | TH05_V1.4, TH05_V1.5, TH05_V1.6 (chip: BL55028) |
|
||||
| [TH05_V1.3](https://pvvx.github.io/TH05-v1.3) | BOOT_TH05D_v19.hex | TH05D_v19.bin | RSH-TH05-V1.3 (chip: BL55072) |
|
||||
| [TH05F](https://pvvx.github.io/TH05F) | BOOT_TH05F_v19.hex | TH05F_v19.bin | TH05Y_V1.1, TH05Y_V1.2, TH05Y_V3.1 (chip: QD01 2332 NT) |
|
||||
| [THB1](https://pvvx.github.io/THB1) | BOOT_THB1_v20.hex | THB1_v20.bin | no |
|
||||
| [THB2](https://pvvx.github.io/THB2) | BOOT_THB2_v20.hex | THB2_v20.bin | no |
|
||||
| [THB3](https://pvvx.github.io/THB3) | BOOT_THB2_v20.hex | THB2_v20.bin | no |
|
||||
| [BTH01](https://pvvx.github.io/BTH01) | BOOT_BTH01_v20.hex | BTH01_v20.bin | no |
|
||||
| [TH05_V1.4](https://pvvx.github.io/TH-05) | BOOT_TH05_v20.hex | TH05_v20.bin | TH05_V1.4, TH05_V1.5, TH05_V1.6 (chip: BL55028) |
|
||||
| [TH05_V1.3](https://pvvx.github.io/TH05-v1.3) | BOOT_TH05D_v20.hex | TH05D_v20.bin | RSH-TH05-V1.3 (chip: BL55072) |
|
||||
| [TH05F](https://pvvx.github.io/TH05F) | BOOT_TH05F_v20.hex | TH05F_v20.bin | TH05Y_V1.1, TH05Y_V1.2, TH05Y_V3.1 (chip: QD01 2332 NT) |
|
||||
| [KEY2](https://pvvx.github.io/iSearching) | BOOT_KEY2_v20.hex | KEY2_v20.bin | SoC ST17H66B |
|
||||
|
||||
|
||||
The main firmware files, BOOT_XXX_vXX.hex (for programming via USB-COM adapter) and XXX_vXX.bin (for OTA), are located in the [bin](bin) directory.
|
||||
|
||||
|
|
@ -96,7 +104,7 @@ The sensors are detected automatically, but have different ports depending on th
|
|||
| 1.7 | <ul><li>Fixed en error (> 42 C) for sensor CHT8305</li></ul> |
|
||||
| 1.8 | <ul><li>Added display of temperature in degrees Fahrenheit</li></ul> |
|
||||
| 1.9 | <ul><li>Fixed the bug of restoring the changed device name after power reset</li></ul> |
|
||||
| 2.0beta2 | <ul><li>Added processing of the CHT832x sensor (Support board TH05Y_v3.1)</li><li>Fixing a bug in BOOT OTA bin files</li><li>Added sleep function when battery is completely discharged</li><li>Added experimental firmware for [iSearching](https://pvvx.github.io/iSearching) key fobs on ST17H66B chip</li></ul> |
|
||||
| 2.0beta3 | <ul><li>Added processing of the CHT832x sensor (Support board TH05Y_v3.1)</li><li>Fixing a bug in BOOT OTA bin files</li><li>Added sleep function when battery is completely discharged</li><li>Added experimental firmware for [iSearching](https://pvvx.github.io/iSearching) key fobs on ST17H66B chip (support "FindMy")</li></ul> |
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Binary file not shown.
BIN
bin/KEY2_v20.bin
BIN
bin/KEY2_v20.bin
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
bin/TH05_v20.bin
BIN
bin/TH05_v20.bin
Binary file not shown.
BIN
bin/THB1_v20.bin
BIN
bin/THB1_v20.bin
Binary file not shown.
BIN
bin/THB2_v20.bin
BIN
bin/THB2_v20.bin
Binary file not shown.
BIN
bin/THB3_v20.bin
BIN
bin/THB3_v20.bin
Binary file not shown.
|
|
@ -11,6 +11,7 @@ SRC_PRJ += battery.c
|
|||
SRC_PRJ += battservice.c
|
||||
SRC_PRJ += ccm.c
|
||||
SRC_PRJ += bthome_beacon.c
|
||||
SRC_PRJ += findmy_beacon.c
|
||||
SRC_PRJ += osal_peripheral.c
|
||||
SRC_PRJ += peripheral_main.c
|
||||
SRC_PRJ += sbp_profile.c
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef __SDK_VER_H__
|
||||
#define __SDK_VER_H__
|
||||
|
||||
//#include "config.h"
|
||||
#include "config.h"
|
||||
|
||||
#define __DEF_CHIP_QFN32__ (0x0001)
|
||||
#define __DEF_CHIP_TSOP16__ (0x0002)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# rdwr_phy62x2.py 11.01.2024 pvvx #
|
||||
# rdwr_phy62x2.py 08.12.2024 pvvx #
|
||||
|
||||
import serial
|
||||
import time
|
||||
|
|
@ -22,9 +22,9 @@ PHY_FLASH_SECTOR_SIZE = 4096
|
|||
PHY_FLASH_SECTOR_MASK = 0xfffff000
|
||||
PHY_WR_BLK_SIZE = 0x2000
|
||||
|
||||
__progname__ = 'PHY62x2 Utility'
|
||||
__progname__ = 'PHY62x2/ST17H66B Utility'
|
||||
__filename__ = 'rdwr_phy62x2.py'
|
||||
__version__ = "11.03.24"
|
||||
__version__ = "08.12.24"
|
||||
|
||||
def ParseHexFile(hexfile):
|
||||
try:
|
||||
|
|
@ -224,10 +224,12 @@ class phyflasher:
|
|||
self._port.flushOutput()
|
||||
self._port.flushInput()
|
||||
time.sleep(0.1)
|
||||
print('PHY62x2: Release RST_N if RTS is not connected...')
|
||||
print('ST17H66B: Turn on the power...')
|
||||
self._port.setDTR(False) #TM (hi)
|
||||
self._port.setRTS(False) #RSTN (hi)
|
||||
self._port.timeout = 0.04
|
||||
ttcl = 50
|
||||
ttcl = 250
|
||||
fct_mode = False
|
||||
pkt = 'UXTDWU' # UXTL16 UDLL48 UXTDWU
|
||||
while ttcl > 0:
|
||||
|
|
@ -240,11 +242,11 @@ class phyflasher:
|
|||
break
|
||||
ttcl = ttcl - 1
|
||||
if ttcl < 1:
|
||||
print('PHY62x2 - Error Reset!')
|
||||
print('Chip Reset error! Response: %s' % read)
|
||||
print('Check connection TX->RX, RX<-TX, RTS->RESET and Chip Power!')
|
||||
self._port.close()
|
||||
exit(4)
|
||||
print('PHY62x2 - Reset Ok')
|
||||
print('Chip Reset Ok. Response: %s' % read)
|
||||
self._port.baudrate = DEF_RUN_BAUD
|
||||
self._port.timeout = 0.2
|
||||
if fct_mode:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "gapbondmgr.h"
|
||||
#include "sensors.h"
|
||||
#include "bthome_beacon.h"
|
||||
#include "findmy_beacon.h"
|
||||
|
||||
#if (DEV_SERVICES & SERVICE_BINDKEY)
|
||||
|
||||
|
|
@ -18,6 +19,7 @@
|
|||
#include "ccm.h"
|
||||
#include "flash_eep.h"
|
||||
#include "ll.h"
|
||||
#include "thb2_peripheral.h"
|
||||
|
||||
/* Encrypted bthome nonce */
|
||||
typedef struct __attribute__((packed)) _bthome_beacon_nonce_t{
|
||||
|
|
@ -118,6 +120,13 @@ uint8_t adv_set_event(void * ped) {
|
|||
#endif
|
||||
|
||||
uint8_t bthome_data_beacon(void * padbuf) {
|
||||
#if (DEV_SERVICES & SERVICE_FINDMY)
|
||||
if (adv_wrk.adv_event == 0 && (cfg.flg & FLG_FINDMY)) {
|
||||
gapRole_AdvEventType = LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT;
|
||||
return findmy_beacon(padbuf);
|
||||
} else
|
||||
gapRole_AdvEventType = LL_ADV_CONNECTABLE_UNDIRECTED_EVT;
|
||||
#endif
|
||||
padv_bthome_noencrypt_t p = (padv_bthome_noencrypt_t)padbuf;
|
||||
p->flag[0] = 0x02; // size
|
||||
p->flag[1] = GAP_ADTYPE_FLAGS; // type
|
||||
|
|
@ -132,6 +141,21 @@ uint8_t bthome_data_beacon(void * padbuf) {
|
|||
p->flag[2] = GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED | GAP_ADTYPE_FLAGS_GENERAL; // Flags
|
||||
p->head.type = GAP_ADTYPE_SERVICE_DATA; // 16-bit UUID
|
||||
p->head.UUID = ADV_BTHOME_UUID16;
|
||||
#if (DEV_SERVICES & SERVICE_BUTTON)
|
||||
#if (DEV_SERVICES & SERVICE_BINDKEY)
|
||||
if (cfg.flg & FLG_ADV_CRYPT) {
|
||||
padv_bthome_encrypt_t pe = (padv_bthome_encrypt_t)p;
|
||||
pe->info = BtHomeID_Info_Encrypt;
|
||||
p->head.size = adv_encrypt(pe->data, adv_set_data(pe->data)) + sizeof(pe->head) - sizeof(pe->head.size) + sizeof(pe->info);
|
||||
} else
|
||||
#endif // (DEV_SERVICES & SERVICE_BINDKEY)
|
||||
{
|
||||
p->info = BtHomeID_Info;
|
||||
p->p_id = BtHomeID_PacketId;
|
||||
p->pid = (uint8)measured_data.count;
|
||||
p->head.size = adv_set_data(p->data) + sizeof(p->head) - sizeof(p->head.size) + sizeof(p->info) + sizeof(p->p_id) + sizeof(p->pid);
|
||||
#else // !(DEV_SERVICES & SERVICE_BUTTON)
|
||||
|
||||
#if (DEV_SERVICES & SERVICE_BINDKEY)
|
||||
if (cfg.flg & FLG_ADV_CRYPT) {
|
||||
padv_bthome_encrypt_t pe = (padv_bthome_encrypt_t)p;
|
||||
|
|
@ -158,7 +182,7 @@ uint8_t bthome_data_beacon(void * padbuf) {
|
|||
{
|
||||
p->head.size = adv_set_data(p->data) + sizeof(p->head) - sizeof(p->head.size) + sizeof(p->info) + sizeof(p->p_id) + sizeof(p->pid);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
return p->head.size + sizeof(p->flag) + 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "logger.h"
|
||||
#include "trigger.h"
|
||||
#include "bthome_beacon.h"
|
||||
#include "findmy_beacon.h"
|
||||
/*********************************************************************/
|
||||
extern gapPeriConnectParams_t periConnParameters;
|
||||
|
||||
|
|
@ -204,6 +205,22 @@ int cmd_parser(uint8_t * obuf, uint8_t * ibuf, uint32_t len) {
|
|||
obuf[1] = 0xff;
|
||||
olen = 2;
|
||||
}
|
||||
#endif
|
||||
#if (DEV_SERVICES & SERVICE_FINDMY)
|
||||
} else if (cmd == CMD_ID_FDMKEY) { // Get/set findmy key
|
||||
if (len == sizeof(findmy_key) + 1) {
|
||||
if(memcmp(findmy_key, &ibuf[1], sizeof(findmy_key))) {
|
||||
memcpy(findmy_key, &ibuf[1], sizeof(findmy_key));
|
||||
flash_write_cfg(findmy_key, EEP_ID_FDK, sizeof(findmy_key));
|
||||
}
|
||||
}
|
||||
if (flash_read_cfg(findmy_key, EEP_ID_FDK, sizeof(findmy_key)) == sizeof(findmy_key)) {
|
||||
memcpy(&obuf[1], findmy_key, sizeof(findmy_key));
|
||||
olen = sizeof(findmy_key) + 1;
|
||||
} else { // No findmy key in EEP!
|
||||
obuf[1] = 0xff;
|
||||
olen = 2;
|
||||
}
|
||||
#endif
|
||||
} else if (cmd == CMD_ID_SERIAL) {
|
||||
memcpy(&obuf[1], devInfoSerialNumber, sizeof(devInfoSerialNumber)-1);
|
||||
|
|
@ -212,10 +229,14 @@ int cmd_parser(uint8_t * obuf, uint8_t * ibuf, uint32_t len) {
|
|||
memcpy(&obuf[1], (uint8_t *)&phy_flash.IdentificationID, 8);
|
||||
olen = 1 + 8;
|
||||
} else if (cmd == CMD_ID_MTU) {
|
||||
if(len >= 2) {
|
||||
if (ibuf[1] <= MTU_SIZE) {
|
||||
ATT_UpdateMtuSize(gapRole_ConnectionHandle, ibuf[1]);
|
||||
obuf[1] = gAttMtuSize[gapRole_ConnectionHandle];
|
||||
} else
|
||||
obuf[1] = 0xff;
|
||||
} else
|
||||
obuf[1] = gAttMtuSize[gapRole_ConnectionHandle];
|
||||
olen = 2;
|
||||
} else if (cmd == CMD_ID_REBOOT) {
|
||||
if(len >= 2) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ typedef enum {
|
|||
CMD_ID_DEV_MAC = 0x10, // Get/Set MAC [+RandMAC], [size]<mac[6][randmac[2]]>
|
||||
CMD_ID_FIX_MAC = 0x11, // Fixed MAC (не безопасная операция, переписывает сектор 0x0 Flash)
|
||||
CMD_ID_BKEY = 0x18, // Get/Set beacon bindkey in EEP
|
||||
CMD_ID_FDMKEY = 0x19, // Get/Set FindMy key in EEP
|
||||
CMD_ID_COMFORT = 0x20, // Get/Set comfort parameters
|
||||
CMD_ID_EXTDATA = 0x22, // Get/Set show ext. data
|
||||
CMD_ID_UTC_TIME = 0x23, // Get/Set utc time (if USE_CLOCK = 1)
|
||||
|
|
@ -48,7 +49,7 @@ typedef enum {
|
|||
CMD_ID_LCD_DUMP = 0x60, // Get/Set lcd buf
|
||||
CMD_ID_LCD_FLG = 0x61, // Start/Stop notify lcd dump and ...
|
||||
CMD_ID_PINCODE = 0x70, // Set new PinCode 0..999999
|
||||
CMD_ID_MTU = 0x71, // Request Mtu Size Exchange (23..255)
|
||||
CMD_ID_MTU = 0x71, // Request Mtu Size Exchange (23..247)
|
||||
CMD_ID_REBOOT = 0x72, // Set Reboot on disconnect
|
||||
CMD_ID_SET_OTA = 0x73, // Extension BigOTA: Get/set address and size OTA, erase sectors
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "thservice.h"
|
||||
#include "thb2_peripheral.h"
|
||||
#include "bthome_beacon.h"
|
||||
#include "findmy_beacon.h"
|
||||
#include "sensors.h"
|
||||
#include "battery.h"
|
||||
#include "sbp_profile.h"
|
||||
|
|
@ -49,8 +50,9 @@ adv_work_t adv_wrk;
|
|||
|
||||
const cfg_t def_cfg = {
|
||||
.flg = FLG_MEAS_NOTIFY | FLG_SHOW_SMILEY,
|
||||
.rf_tx_power = RF_PHY_TX_POWER_0DBM,
|
||||
.advertising_interval = 80, // 80 * 62.5 = 5000 ms
|
||||
.rf_tx_power = RF_PHY_TX_POWER_MAX, // RF_PHY_TX_POWER_0DBM,
|
||||
.adv_event_cnt = 16,
|
||||
.advertising_interval = DEF_ADV_INERVAL/100, // 80 * 62.5 = 5000 ms
|
||||
.measure_interval = 2, // 5 * 2 = 10 sec
|
||||
.batt_interval = 60, // 60 sec
|
||||
.connect_latency = DEFAULT_DESIRED_SLAVE_LATENCY, // 30*(29+1) = 900 ms
|
||||
|
|
@ -163,6 +165,8 @@ void test_config(void) {
|
|||
if(cfg.measure_interval < 2)
|
||||
cfg.measure_interval = 2;
|
||||
adv_wrk.measure_interval_ms = (cfg.advertising_interval * cfg.measure_interval * 625) / 10;
|
||||
if(cfg.adv_event_cnt < 6)
|
||||
cfg.adv_event_cnt = 16;
|
||||
}
|
||||
|
||||
void load_eep_config(void) {
|
||||
|
|
@ -191,11 +195,15 @@ void load_eep_config(void) {
|
|||
if (flash_read_cfg(&clkt.delta_time, EEP_ID_TIM, sizeof(&clkt.delta_time)) != sizeof(&clkt.delta_time)) {
|
||||
clkt.delta_time = 0;
|
||||
}
|
||||
#endif
|
||||
#if (DEV_SERVICES & SERVICE_FINDMY)
|
||||
flash_read_cfg(findmy_key, EEP_ID_FDK, sizeof(findmy_key));
|
||||
#endif
|
||||
}
|
||||
#if (DEV_SERVICES & SERVICE_HISTORY)
|
||||
memo_init();
|
||||
#endif
|
||||
|
||||
test_config();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
//#define SERVICE_IUS 0x00080000 // use I and U sensor (INA226) (пока нет реализации)
|
||||
//#define SERVICE_PLM 0x00100000 // use PWM-RH and NTC (пока нет реализации)
|
||||
#define SERVICE_BUTTON 0x00200000 // кнопка, активность только при нажатии
|
||||
#define SERVICE_FINDMY 0x00400000 // FindMy
|
||||
|
||||
#define OTA_TYPE_NONE 0 // нет OTA, только переключение из APP на boot прошивку
|
||||
#define OTA_TYPE_BOOT SERVICE_OTA // вариант для прошивки boot + OTA
|
||||
|
|
@ -362,11 +363,13 @@
|
|||
#if OTA_TYPE == OTA_TYPE_BOOT
|
||||
#define DEV_SERVICES (OTA_TYPE \
|
||||
| SERVICE_BUTTON \
|
||||
| SERVICE_FINDMY \
|
||||
| SERVICE_BINDKEY \
|
||||
)
|
||||
#else
|
||||
#define DEV_SERVICES (OTA_TYPE \
|
||||
| SERVICE_BUTTON \
|
||||
| SERVICE_FINDMY \
|
||||
| SERVICE_BINDKEY \
|
||||
)
|
||||
#endif
|
||||
|
|
@ -382,6 +385,8 @@
|
|||
#define LED_OFF 0
|
||||
|
||||
#define GPIO_BUZZER GPIO_P09
|
||||
#define BUZZER_ON 1
|
||||
#define BUZZER_OFF 0
|
||||
|
||||
//#define GPIO_INP GPIO_P15
|
||||
|
||||
|
|
@ -398,6 +403,7 @@
|
|||
#error "Not SERVICE_TH_TRG!"
|
||||
#endif
|
||||
|
||||
|
||||
// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
|
||||
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 24 // 12 -> 15 ms
|
||||
// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
|
||||
|
|
@ -413,7 +419,7 @@ typedef struct _cfg_t {
|
|||
uint8_t rf_tx_power; // 0..0x3F
|
||||
uint8_t advertising_interval; // multiply by 62.5 for value in ms (1..160, 62.5 ms .. 10 sec)
|
||||
uint8_t connect_latency; // +1 x 0.03 sec ( = connection interval), Tmin = 1*30 = 30 ms, Tmax = 256 * 30 = 7680 ms
|
||||
uint8_t reserved1;
|
||||
uint8_t adv_event_cnt;
|
||||
|
||||
uint8_t measure_interval; // measure TH sensor count * advertising_interval
|
||||
uint8_t batt_interval; // measure battery * seconds
|
||||
|
|
@ -430,6 +436,7 @@ extern const cfg_t def_cfg;
|
|||
#define FLG_DISPLAY_OFF 0x00000010 // отключить дисплей
|
||||
#define FLG_ADV_CRYPT 0x00000020 // Зашифрованная BLE реклама (bindkey)
|
||||
#define FLG_SHOW_TF 0x00000040 // Show temperature in F.
|
||||
#define FLG_FINDMY 0x00000080 // FindMy
|
||||
|
||||
typedef struct _adv_work_t {
|
||||
uint32_t measure_interval_ms;
|
||||
|
|
|
|||
40
bthome_phy6222/source/findmy_beacon.c
Normal file
40
bthome_phy6222/source/findmy_beacon.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* findmy_beacon.c
|
||||
*
|
||||
* Created on: 8 дек. 2024 г.
|
||||
* Author: pvvx
|
||||
*/
|
||||
#include "rom_sym_def.h"
|
||||
#include "types.h"
|
||||
#include "config.h"
|
||||
|
||||
#if (DEV_SERVICES & SERVICE_FINDMY)
|
||||
|
||||
uint8_t findmy_key[22];
|
||||
|
||||
typedef struct __attribute__((packed)) _adv_bthome_noencrypt_t {
|
||||
uint8_t head[7];
|
||||
uint8_t key[22];
|
||||
uint8_t end[2];
|
||||
} adv_findmy_t, * padv_findmy_t;
|
||||
|
||||
static uint8 findmy_head[] = {
|
||||
0x1e, /* Length (30) */
|
||||
0xff, /* Manufacturer Specific Data (type 0xff) */
|
||||
0x4c, 0x00, /* Company ID (Apple) */
|
||||
0x12, 0x19, /* Offline Finding type and length */
|
||||
0x00 /* State */
|
||||
};
|
||||
|
||||
|
||||
|
||||
uint8_t findmy_beacon(void * padbuf) {
|
||||
padv_findmy_t p = (padv_findmy_t)padbuf;
|
||||
memcpy(p->head, findmy_head, sizeof(findmy_head));
|
||||
memcpy(p->key, findmy_key, sizeof(findmy_key));
|
||||
p->end[0] = 0;
|
||||
p->end[1] = 0;
|
||||
return sizeof(adv_findmy_t);
|
||||
}
|
||||
|
||||
#endif // USE_FINDMY
|
||||
14
bthome_phy6222/source/findmy_beacon.h
Normal file
14
bthome_phy6222/source/findmy_beacon.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* findmy_beacon.h
|
||||
*
|
||||
* Created on: 8 дек. 2024 г.
|
||||
* Author: pvvx
|
||||
*/
|
||||
|
||||
#ifndef SOURCE_FINDMY_BEACON_H_
|
||||
#define SOURCE_FINDMY_BEACON_H_
|
||||
|
||||
extern uint8_t findmy_key[22];
|
||||
uint8_t findmy_beacon(void * padbuf);
|
||||
|
||||
#endif /* SOURCE_FINDMY_BEACON_H_ */
|
||||
|
|
@ -23,6 +23,7 @@ extern "C" {
|
|||
#define EEP_ID_TIM (0x0ADA) // EEP ID time adjust
|
||||
#define EEP_ID_KEY (0xBC0D) // EEP ID bindkey
|
||||
#define EEP_ID_VER (0x5555) // EEP ID blk: unsigned int = minimum supported version
|
||||
#define EEP_ID_FDK (0xF1D1) // EEP ID findmy key
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef FLASH_BASE_ADDR
|
||||
#define FLASH_BASE_ADDR 0x11000000
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ static void ble_mem_init_config(void) {
|
|||
static void hal_rfphy_init(void) {
|
||||
//Watchdog_Init(NULL);
|
||||
//============config the txPower
|
||||
g_rfPhyTxPower = RF_PHY_TX_POWER_0DBM;
|
||||
g_rfPhyTxPower = RF_PHY_TX_POWER_MAX;
|
||||
//============config BLE_PHY TYPE
|
||||
g_rfPhyPktFmt = PKT_FMT_BLE1M;
|
||||
//============config RF Frequency Offset
|
||||
|
|
|
|||
|
|
@ -221,13 +221,15 @@ typedef struct __attribute__((packed)) _measured_flg_t {
|
|||
|
||||
typedef struct _measured_data_t {
|
||||
uint16_t count;
|
||||
uint8_t button;
|
||||
uint8_t none1;
|
||||
int16_t none2;
|
||||
uint16_t battery_mv; // mV
|
||||
uint8_t battery; // 0..100 %
|
||||
measured_flg_t flg;
|
||||
uint8_t button;
|
||||
} measured_data_t;
|
||||
|
||||
#define send_len_measured_data 5
|
||||
#define send_len_measured_data 10
|
||||
|
||||
extern measured_data_t measured_data;
|
||||
|
||||
|
|
|
|||
|
|
@ -153,10 +153,17 @@ static void set_mac(void)
|
|||
// Tuya mac[0:3]
|
||||
ownPublicAddr[3] = 0x8d;
|
||||
ownPublicAddr[4] = 0x1f;
|
||||
#if (DEV_SERVICES & SERVICE_FINDMY)
|
||||
ownPublicAddr[5] = 0xf8; // random mac
|
||||
#else
|
||||
ownPublicAddr[5] = 0x38;
|
||||
#endif
|
||||
}
|
||||
flash_write_cfg(ownPublicAddr, EEP_ID_MAC, MAC_LEN);
|
||||
}
|
||||
#if (DEV_SERVICES & SERVICE_FINDMY)
|
||||
ownPublicAddr[5] |= 0xc0; // random mac
|
||||
#endif
|
||||
pGlobal_config[MAC_ADDRESS_LOC] = (uint32_t)ownPublicAddr;
|
||||
// device name
|
||||
set_dev_name();
|
||||
|
|
@ -225,7 +232,7 @@ static void adv_measure(void) {
|
|||
if(clkt.utc_time_tik - adv_wrk.rds_timer_tik >= (RDS_EVENT_STEP_SEC << 15)) { // шаг дублирования передачи 30 минут
|
||||
adv_wrk.rds_timer_tik = clkt.utc_time_tik;
|
||||
adv_wrk.adv_event = 1;
|
||||
adv_wrk.adv_reload_count = RDS_EVENT_ADV_COUNT; // 16
|
||||
adv_wrk.adv_reload_count = cfg.adv_event_cnt; // 16
|
||||
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
|
||||
set_new_adv_interval(DEF_EVENT_ADV_INERVAL); // 50 ms (in 625us)
|
||||
return;
|
||||
|
|
@ -299,15 +306,30 @@ static void adv_measure(void) {
|
|||
#endif
|
||||
#if (DEV_SERVICES & SERVICE_BUTTON)
|
||||
if(adv_wrk.adv_event) { // передавались event ?
|
||||
adv_wrk.adv_reload_count = RDS_EVENT_ADV_COUNT;
|
||||
#ifdef GPIO_LED
|
||||
hal_gpio_write(GPIO_LED, LED_OFF);
|
||||
#endif
|
||||
adv_wrk.adv_reload_count = cfg.adv_event_cnt;
|
||||
if(!measured_data.button) {
|
||||
if(adv_wrk.new_battery) {
|
||||
adv_wrk.new_battery = 0;
|
||||
check_battery();
|
||||
}
|
||||
#ifdef GPIO_BUZZER
|
||||
hal_gpio_write(GPIO_BUZZER, BUZZER_ON);
|
||||
#endif
|
||||
measured_data.count++;
|
||||
#ifdef GPIO_BUZZER
|
||||
hal_gpio_write(GPIO_BUZZER, BUZZER_OFF);
|
||||
#endif
|
||||
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
|
||||
#ifdef GPIO_BUZZER
|
||||
hal_gpio_write(GPIO_BUZZER, BUZZER_ON);
|
||||
#endif
|
||||
adv_wrk.adv_event = 0;
|
||||
#ifdef GPIO_BUZZER
|
||||
hal_gpio_write(GPIO_BUZZER, BUZZER_OFF);
|
||||
#endif
|
||||
set_new_adv_interval(DEF_EVENT_ADV_INERVAL);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -543,6 +565,15 @@ void SimpleBLEPeripheral_Init( uint8_t task_id )
|
|||
// Set the GAP Role Parameters
|
||||
// device starts advertising upon initialization
|
||||
gatrole_advert_enable(FALSE);
|
||||
#if (DEV_SERVICES & SERVICE_FINDMY)
|
||||
if (cfg.flg & FLG_FINDMY) {
|
||||
extern uint8_t findmy_beacon(void * padbuf);
|
||||
gapRole_AdvEventType = LL_ADV_NONCONNECTABLE_UNDIRECTED_EVT;
|
||||
gapRole_AdvertDataLen = findmy_beacon((void *)gapRole_AdvertData);
|
||||
} else {
|
||||
gapRole_AdvEventType = LL_ADV_CONNECTABLE_UNDIRECTED_EVT;
|
||||
}
|
||||
#endif
|
||||
// gapRole_AdvertOffTime = 0; // already set default
|
||||
GAP_UpdateAdvertisingData( gapRole_TaskID, TRUE, gapRole_AdvertDataLen, gapRole_AdvertData );
|
||||
GAP_UpdateAdvertisingData( gapRole_TaskID, FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
|
||||
|
|
@ -777,7 +808,7 @@ uint16_t BLEPeripheral_ProcessEvent( uint8_t task_id, uint16_t events )
|
|||
if(gapRole_AdvEnabled) {
|
||||
measured_data.count++;
|
||||
adv_wrk.adv_event = 1;
|
||||
adv_wrk.adv_reload_count = RDS_EVENT_ADV_COUNT;
|
||||
adv_wrk.adv_reload_count = cfg.adv_event_cnt;
|
||||
adv_wrk.rds_timer_tik = clkt.utc_time_tik - (RDS_EVENT_DOUBLE_SEC << 15);
|
||||
LL_SetAdvData(bthome_data_beacon((void *) gapRole_AdvertData), gapRole_AdvertData);
|
||||
set_new_adv_interval(DEF_EVENT_ADV_INERVAL); // 50ms, actual time * 625us
|
||||
|
|
|
|||
|
|
@ -23,14 +23,18 @@ extern "C"
|
|||
/*********************************************************************
|
||||
* CONSTANTS
|
||||
*/
|
||||
|
||||
#if (DEV_SERVICES & SERVICE_BUTTON)
|
||||
#define DEF_ADV_INERVAL 16000 // = 10 sec, actual time = advInt * 625us
|
||||
#define DEF_ADV_INERVAL_MS ((DEF_ADV_INERVAL*625)/1000) // 10000 ms
|
||||
#else
|
||||
#define DEF_ADV_INERVAL 8000 // = 5 sec, actual time = advInt * 625us
|
||||
#define DEF_ADV_INERVAL_MS ((DEF_ADV_INERVAL*625)/1000) // 5000 ms
|
||||
#endif
|
||||
#define DEF_CON_ADV_INERVAL 2500 // 1.5625 sec
|
||||
#define DEF_CON_ADV_INERVAL_MS ((DEF_CON_ADV_INERVAL*625)/1000) // 1562 ms
|
||||
#if (DEV_SERVICES & SERVICE_BUTTON)
|
||||
#define DEF_EVENT_ADV_INERVAL 120 // 75 ms
|
||||
#define RDS_EVENT_ADV_COUNT 16 // 16*75 = 1200 ms
|
||||
#define DEF_EVENT_ADV_INERVAL 200 // 95 ms
|
||||
#define RDS_EVENT_ADV_COUNT 32 // 32*95 = 3040 ms
|
||||
#else
|
||||
#define DEF_EVENT_ADV_INERVAL 80 // 50 ms
|
||||
#define RDS_EVENT_ADV_COUNT 16 // 16*50 = 800 ms
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<html class="phy6222Class"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PHY62x2 BTHome v1.6</title>
|
||||
<title>PHY62x2 BTHome v1.7</title>
|
||||
<!--<link rel="stylesheet" type="text/css" href="styles.css" />
|
||||
<link rel="stylesheet" type="text/css" href="chart.css" />
|
||||
<script type="text/javascript" src="dygraph.min.js" /></script> /-->
|
||||
|
|
@ -558,7 +558,7 @@ div#divChart {
|
|||
READING_BYTES: { en: 'Reading %s bytes at', ru: 'Чтение %s байт по адресу' },
|
||||
WRITING_BYTES: { en: 'Writing %s bytes at', ru: 'Запись %s байт по адресу' },
|
||||
BLOCK_LENGTH_RANGE: { en: 'Block length must be 1 to 16 bytes', ru: 'длина блока от 1 до 16 байт' },
|
||||
COMMAND_LENGTH_RANGE: { en: 'Command length must be 1 to 20 bytes', ru: 'длина команды от 1 до 20 байт' },
|
||||
COMMAND_LENGTH_RANGE: { en: 'Command length must be 1 to MTU bytes', ru: 'длина команды от 1 до MTU байт' },
|
||||
BATTERY: { en: 'Battery', ru: 'Батарея' },
|
||||
MILLIVOLT: { en: 'mV', ru: 'мВ' },
|
||||
MEMO_EMPTY: { en: 'Memo is empty', ru: 'Пока нет истории' },
|
||||
|
|
@ -589,6 +589,7 @@ div#divChart {
|
|||
CORRECT_DEVICENAME_LENGTH: { en: 'Save DeviceName...', ru: 'Сохранение имени устройства...' },
|
||||
INVALID_DEVICENAME_LENGTH: { en: 'Devicename length must be 1 to 19 bytes (UTF-8 characters consume 2 bytes)', ru: 'Имя устройства должно быть от 1 до 19 символов, включая кодирование UTF-8' },
|
||||
INVALID_BINDKEY_LENGTH: { en: 'Bindkey must be 16 bytes, hex encoded (=32 characters)', ru: 'BindKey должен соднержать 16 байт в HEX виде (32 символа)' },
|
||||
INVALID_FINDMYKEY_LENGTH: { en: 'FindMyKey must be 22 bytes, hex encoded (=44 characters)', ru: 'BindKey должен соднержать 22 байта в HEX виде (44 символа)' },
|
||||
UPLOAD_FIRMWARE: { en: 'Download firmware file', ru: 'Загрузка firmware файла' },
|
||||
WARNING_BOOT_FW: { en: 'Attention!: Uploading boot FW is not safe. In order to avoid firmware failure use a fresh battery!', ru: 'Внимание!: Обновление Boot fw не безопасно. Во избежание сбоя прошивки желательно использование полной батареи!' },
|
||||
MEMO_OFF: {en: 'Disabled', ru: 'Отключено'},
|
||||
|
|
@ -646,6 +647,7 @@ const SERVICE_INS = 0x00000800; // Maintenance of input pins
|
|||
const SERVICE_TIME_ADJUST = 0x00001000; // Time account correction function
|
||||
const SERVICE_HARD_CLOC = 0x00002000; // Real hours RTC
|
||||
const SERVICE_TH_TRG = 0x00004000; // temperature and humidity
|
||||
const SERVICE_BUTTON = 0x00200000 // кнопка, активность только при нажатии
|
||||
|
||||
var bluetoothDevice, gattServer, otaCharacteristic, cmdCharacteristic, infoService;
|
||||
|
||||
|
|
@ -912,21 +914,21 @@ function doConnect() {
|
|||
|
||||
function auxControls(state)
|
||||
{
|
||||
if ( devSrv.services & SERVICE_SCREEN ) {
|
||||
if (devSrv.services & SERVICE_SCREEN) {
|
||||
$('tblChkCfg').style.display = "block";
|
||||
$('tblComfort').style.display = "block";
|
||||
} else {
|
||||
$('tblChkCfg').style.display = "none";
|
||||
$('tblComfort').style.display = "none";
|
||||
}
|
||||
if ( devSrv.services & SERVICE_BINDKEY ) {
|
||||
if (devSrv.services & SERVICE_BINDKEY) {
|
||||
$('labBindKey').style.display = "block";
|
||||
$('divBindKey').style.display = "block";
|
||||
} else {
|
||||
$('labBindKey').style.display = "none";
|
||||
$('divBindKey').style.display = "none";
|
||||
}
|
||||
if ( devSrv.services & SERVICE_TH_TRG )
|
||||
if (devSrv.services & SERVICE_TH_TRG)
|
||||
$('tblTrigger').style.display = "block";
|
||||
else
|
||||
$('tblTrigger').style.display = "none";
|
||||
|
|
@ -937,6 +939,25 @@ function auxControls(state)
|
|||
$('tblTriggerKeys').style.display = "none";
|
||||
$('hrPres').style.display = "none";
|
||||
}
|
||||
if (devSrv.services & SERVICE_THS) {
|
||||
$('tblSensorTH').style.display = "block";
|
||||
} else {
|
||||
$('tblSensorTH').style.display = "none";
|
||||
}
|
||||
if (devSrv.services & SERVICE_BUTTON) {
|
||||
$('tblButton').style.display = "block";
|
||||
$('trMeasStep').style.display = "none";
|
||||
$('divFindMyKey').style.display = "block";
|
||||
} else {
|
||||
$('tblButton').style.display = "none";
|
||||
$('trMeasStep').style.display = "block";
|
||||
$('divFindMyKey').style.display = "none";
|
||||
}
|
||||
if (devSrv.services & SERVICE_HISTORY) {
|
||||
$('trHistStep').style.display = "block";
|
||||
} else {
|
||||
$('trHistStep').style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function disableControls(state)
|
||||
|
|
@ -1387,7 +1408,7 @@ function writeAddr(addr, data) {
|
|||
function writeCmd(data) {
|
||||
if(cmdCharacteristic) {
|
||||
len = data.length;
|
||||
if((len > 0) && (len <= 20)) {
|
||||
if((len > 0) && (len <= 40)) { // TODO: MTU
|
||||
let blk = new Uint8Array(data);
|
||||
cmdCharacteristic.writeValue(blk);
|
||||
} else
|
||||
|
|
@ -1414,7 +1435,7 @@ function writeAddress() {
|
|||
|
||||
function sendCommand() {
|
||||
let data = hexToBytes($('inpCmdData').value);
|
||||
if(data.length != 0 && data.length <= 20)
|
||||
if(data.length != 0 && data.length <= 40) // TODO:MTU
|
||||
writeCmd(data);
|
||||
else
|
||||
console.log(`${i18n.getTag('ERROR')}: ${i18n.getTag('COMMAND_LENGTH_RANGE')}!`);
|
||||
|
|
@ -1428,6 +1449,7 @@ function showConfig() {
|
|||
$('chkCfgLcdOff').checked = (devCfg.flg & 16) != 0;
|
||||
$('chkCfgBindKey').checked = (devCfg.flg & 32) != 0;
|
||||
$('chkCfgFahrenheit').checked = (devCfg.flg & 64) != 0;
|
||||
$('chkCfgFindMy').checked = (devCfg.flg & 128) != 0;
|
||||
|
||||
let txPwr = 31;
|
||||
el = $('selTxPwr');
|
||||
|
|
@ -1451,6 +1473,7 @@ function showConfig() {
|
|||
$('lblAverInt').innerHTML = "= " + hsti.toFixed(1) + ` ${i18n.getTag('SECONDS')}`;
|
||||
}
|
||||
$('inpBatInt').value = devCfg.batt_interval; // в секундах, минимум 2 секунды, но кратно интервалу рекламы
|
||||
$('inpEvAdvCnt').value = devCfg.event_adv_count;
|
||||
}
|
||||
|
||||
function parseBlkCustom(value) {
|
||||
|
|
@ -1599,7 +1622,7 @@ function parseBlkCustom(value) {
|
|||
devCfg.tx_power = value.getUint8(5);
|
||||
devCfg.advertising_interval = value.getUint8(6);
|
||||
devCfg.connect_latency = value.getUint8(7);
|
||||
devCfg.reserved1 = value.getUint8(8);
|
||||
devCfg.event_adv_count = value.getUint8(8);
|
||||
devCfg.measure_interval = value.getUint8(9);
|
||||
devCfg.batt_interval = value.getUint8(10);
|
||||
devCfg.averaging_measurements = value.getUint8(11);
|
||||
|
|
@ -1609,6 +1632,7 @@ function parseBlkCustom(value) {
|
|||
+ ", tx: " + devCfg.tx_power
|
||||
+ ", adi: " + devCfg.advertising_interval
|
||||
+ ", cli: " + devCfg.connect_latency
|
||||
+ ", eac: " + devCfg.event_adv_count
|
||||
+" , msi: " + devCfg.measure_interval
|
||||
+ ", bti: " + devCfg.batt_interval
|
||||
+ ", avi: " + devCfg.averaging_measurements);
|
||||
|
|
@ -1645,6 +1669,17 @@ function parseBlkCustom(value) {
|
|||
console.log('blk: ' + dump8(value, value.byteLength));
|
||||
$("inpBindKey").value = i18n.getTag('NOT_SUPPORTED');
|
||||
}
|
||||
} else if(blkId == 0x19 && len >= 1) { // Get/set findmy bkey in EEP
|
||||
if(len > 22) {
|
||||
devKeys.cfindmykey = value.buffer.slice(1,23);
|
||||
let s = bytesToHex(devKeys.cfindmykey,22);
|
||||
addLog("FindMy key # "+ s);
|
||||
$("inpFindMyKey").value = s;
|
||||
} else {
|
||||
addLog(`${i18n.getTag('READ_ERROR')} FindMy key!`);
|
||||
console.log('blk: ' + dump8(value, value.byteLength));
|
||||
$("inpFindMyKey").value = "none";
|
||||
}
|
||||
} else if(blkId == 0x23 && len >= 4) {
|
||||
devTime.cur = value.getUint32(1,true);
|
||||
console.log('Device Time: 0x' + hex(devTime.cur, 8));
|
||||
|
|
@ -1739,6 +1774,12 @@ function parseBlkCustom(value) {
|
|||
let mac_txt = bytesToHex(mac);
|
||||
$("inpDevMAC").value = mac_txt;
|
||||
addLog(`${i18n.getTag('DEVICE_MAC')}: ${mac_txt}`);
|
||||
} else if(blkId == 0x71 && len >= 1) {
|
||||
devInfo.mtu = value.getUint8(1);
|
||||
if(devInfo.mtu == 255 || devInfo.mtu == 0)
|
||||
addLog('Error set MTU size!');
|
||||
else
|
||||
addLog('MTU size: ' + devInfo.mtu);
|
||||
} else {
|
||||
console.log('blk: ' + dump8(value, value.byteLength));
|
||||
addLog(`${i18n.getTag('COMMAND_RESPONSE')} (${hex(blkId,2)}): ${bytesToHex(value.buffer.slice(1))}`);
|
||||
|
|
@ -1802,6 +1843,7 @@ function chkDevCfg() {
|
|||
devCfg.flg |= ($('chkCfgLcdOff').checked) ? 16 : 0;
|
||||
devCfg.flg |= ($('chkCfgBindKey').checked) ? 32 : 0;
|
||||
devCfg.flg |= ($('chkCfgFahrenheit').checked) ? 64 : 0;
|
||||
devCfg.flg |= ($('chkCfgFindMy').checked) ? 128 : 0;
|
||||
devCfg.tx_power = $('selTxPwr').value & 0x3f; // 0..0x1f -> -20..+5 dBm ? нелинейное 0x1f = +0 дБм
|
||||
let connect_latency = parseInt($('inpLat').value); // = (connect_latency + 1)*30 ms
|
||||
if (connect_latency < 0) {
|
||||
|
|
@ -1829,6 +1871,11 @@ function chkDevCfg() {
|
|||
devCfg.averaging_measurements = 0;
|
||||
if(devCfg.averaging_measurements > 255)
|
||||
devCfg.averaging_measurements = 255;
|
||||
devCfg.event_adv_count = parseInt($('inpEvAdvCnt').value);
|
||||
if(devCfg.event_adv_count < 6)
|
||||
devCfg.event_adv_count = 6;
|
||||
if(devCfg.event_adv_count > 255)
|
||||
devCfg.event_adv_count = 255;
|
||||
devCfg.batt_interval = parseInt($('inpBatInt').value);
|
||||
if(devCfg.batt_interval < 2) // в секундах, минимум 2 секунды, но кратно интервалу рекламы
|
||||
devCfg.batt_interval = 2;
|
||||
|
|
@ -1845,7 +1892,7 @@ function setDevCfg() {
|
|||
devCfg.tx_power,
|
||||
devCfg.advertising_interval,
|
||||
devCfg.connect_latency,
|
||||
devCfg.reserved1,
|
||||
devCfg.event_adv_count,
|
||||
devCfg.measure_interval,
|
||||
devCfg.batt_interval,
|
||||
devCfg.averaging_measurements,
|
||||
|
|
@ -2033,6 +2080,33 @@ function setBindKey() {
|
|||
addLog(`${i18n.getTag('INVALID_BINDKEY_LENGTH')}!`)
|
||||
}
|
||||
}
|
||||
function getGetFindMyKey() {
|
||||
if(cmdCharacteristic != null) {
|
||||
cmdCharacteristic.writeValue(new Uint8Array([0x19])).catch(error => { addLog("getFindmyKey() Error: " + error); });
|
||||
}
|
||||
}
|
||||
function setFindMyKey() {
|
||||
if(cmdCharacteristic != null) {
|
||||
let bk = $("inpFindMyKey").value;
|
||||
if(bk.length == 44) {
|
||||
let bkey = hexToBytes(bk);
|
||||
if(bkey.length == 22) {
|
||||
let blk = new Uint8Array(23);
|
||||
blk.set(bkey,1);
|
||||
blk[0] = 0x19;
|
||||
addLog(`${i18n.getTag('WRITE')} FindMy: ${bytesToHex(blk.slice(1))}`);
|
||||
cmdCharacteristic.writeValue(blk).catch(error => { addLog("setFindMyKey() Error: " + error); });
|
||||
return;
|
||||
}
|
||||
}
|
||||
addLog(`${i18n.getTag('INVALID_FINDMYKEY_LENGTH')}!`)
|
||||
}
|
||||
}
|
||||
|
||||
function setMaxMTU() {
|
||||
if(cmdCharacteristic != null)
|
||||
cmdCharacteristic.writeValue(new Uint8Array([0x71,240])).catch(error => { addLog("setMaxMTU() Error: " + error); });
|
||||
}
|
||||
|
||||
function readFile(file) {
|
||||
|
||||
|
|
@ -2373,6 +2447,12 @@ window.onload = function() {
|
|||
<td><label><input type="checkbox" id="chkCfgFahrenheit"/><span data-i18ntag="SHOW_TEMPF">Показывать температуру в градусах Фаренгейта</span></label></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table id="tblButton">
|
||||
<tr>
|
||||
<td><label><input type="checkbox" id="chkCfgFindMy"/>FindMy</label></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
|
|
@ -2401,13 +2481,16 @@ window.onload = function() {
|
|||
</tr>
|
||||
</table>
|
||||
<table>
|
||||
<tr id="trMeasStep">
|
||||
<td><span data-i18ntag="MEASUREMENT_STEP">Шаг измерений</span>: <input size="4" type="text" id="inpMeasInt" onchange="chkDevCfg()" maxlength="8" title="Опрос датчика в интервалах BLE рекламы, минимум 2 интервала рекламы"><label id="lblMeasInt"></label><span data-i18ntag="MS">мс</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span data-i18ntag="MEASUREMENT_STEP">Шаг измерений</span>: <input size="4" type="text" id="inpMeasInt" onchange="chkDevCfg()" maxlength="8" title="Опрос датчика в интервалах BLE рекламы, минимум 2 интервала рекламы"><label id="lblMeasInt"></label></td>
|
||||
<td><span>Number of event transmissions</span>: <input size="4" type="text" id="inpEvAdvCnt" maxlength="8" title="В штуках, минимум 6, максимум 255"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><span data-i18ntag="BAT_INTERVAL">Опрос батареи</span>: <input size="4" type="text" id="inpBatInt" maxlength="8" title="В секундах, обрабатывается кратно интервалу BLE рекламы, минимум 2 секунды"><span data-i18ntag="SECONDS">сек.</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr id="trHistStep">
|
||||
<td><span data-i18ntag="HISTORY_INTERVAL">Запись истории</span>: <input size="4" type="text" id="inpAverInt" onchange="chkDevCfg()" maxlength="8" title="Запись истории: 0 - отключена, 1...255 * шаг опроса датчика = интервал записи истории"><label id="lblAverInt"></label></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
@ -2422,6 +2505,7 @@ window.onload = function() {
|
|||
<td><label id="lbDeltaTime"></label></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="hrPres">
|
||||
<hr>
|
||||
<table id="tblComfort">
|
||||
<tr>
|
||||
|
|
@ -2448,9 +2532,9 @@ window.onload = function() {
|
|||
<td><button type="button"id="btnSetTrg" onclick="setTrgCfg()" data-i18ntag="WRITE">Записать</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr id="hrPres">
|
||||
<hr>
|
||||
<span data-i18ntag="SENSOR_PARAMS">Параметры сенсора</span> <b><label id="lblSensor">?</label></b>
|
||||
<table>
|
||||
<table id="tblSensorTH">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th data-i18ntag="TEMPERATURE">Температура</th>
|
||||
|
|
@ -2475,6 +2559,7 @@ window.onload = function() {
|
|||
<button type="button"id="btnSetSens" onclick="setSensCfg()" data-i18ntag="WRITE">Записать</button>
|
||||
<button type="button"id="btnRstSens" onclick="resetSensCfg()" title="Восстановить стандартные параметры сенсора" data-i18ntag="RESTORE">Восстановить</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tabOTA" class="tabcontent">
|
||||
<p><span data-i18ntag="FILE">Файл(ы) прошивки</span>:
|
||||
|
|
@ -2513,7 +2598,7 @@ window.onload = function() {
|
|||
<tr>
|
||||
<td style="width:100px;"><span data-i18ntag="COMMAND">Команда</span>:</td>
|
||||
<td><button type="button" id="btnSendCommand" onclick="sendCommand()" style="width:120px;" data-i18ntag="SEND">Выполнить</button></td>
|
||||
<td><input type="text" id="inpCmdData" value="55" maxlength="40"></td>
|
||||
<td><input type="text" id="inpCmdData" value="55" maxlength="50"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
|
|
@ -2546,6 +2631,21 @@ window.onload = function() {
|
|||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div id="divFindMyKey">
|
||||
<hr>
|
||||
<table>
|
||||
<tr>
|
||||
<td style="width:100px;">FindMy Key:</td>
|
||||
<td><button type="button" id="btnGetFindMyKey" onclick="getGetFindMyKey()" data-i18ntag="READ">Прочитать</button></td>
|
||||
<td><input size="43" maxlength="44" title="FindMy Key должен содержать 22 байта в hex виде" type="text" id="inpFindMyKey" value="?"></td>
|
||||
<td><button type="button" id="btnSetFindMyKey" onclick="setFindMyKey()" data-i18ntag="WRITE">Записать</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<hr>
|
||||
<button type="button" id="btnSetMaxMTU" onclick="setMaxMTU()">SetMaxMTU</button>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<button type="button" onclick="clearLog()" data-i18ntag="CLEAN_LOG">Очистить лог</button>
|
||||
|
|
|
|||
11
fw.json
11
fw.json
|
|
@ -6,7 +6,9 @@
|
|||
"bin/THB1_v20.bin",
|
||||
"bin/TH05D_v20.bin",
|
||||
"bin/TH05F_v20.bin",
|
||||
"bin/THB3_v20.bin"],
|
||||
"bin/THB3_v20.bin",
|
||||
"?","?","?",
|
||||
"bin/KEY2_v20.bin"],
|
||||
"custom":[
|
||||
"bin/THB2_v19.bin",
|
||||
"bin/BTH01_v19.bin",
|
||||
|
|
@ -15,7 +17,8 @@
|
|||
"bin/THB1_v19.bin",
|
||||
"bin/TH05D_v19.bin",
|
||||
"bin/TH05F_v19.bin",
|
||||
"bin/THB3_v19.bin"],
|
||||
"bin/THB3_v19.bin",
|
||||
"?","?","?","?"],
|
||||
"updateboot":[
|
||||
"update_boot/BOOT_THB2_v20.bin",
|
||||
"update_boot/BOOT_BTH01_v20.bin",
|
||||
|
|
@ -24,5 +27,7 @@
|
|||
"update_boot/BOOT_THB1_v20.bin",
|
||||
"update_boot/BOOT_TH05D_v20.bin",
|
||||
"update_boot/BOOT_TH05F_v20.bin",
|
||||
"update_boot/BOOT_THB3_v20.bin"]
|
||||
"update_boot/BOOT_THB3_v20.bin",
|
||||
"?","?","?",
|
||||
"update_boot/BOOT_KEY2_v20.bin"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# rdwr_phy62x2.py 11.01.2024 pvvx #
|
||||
# rdwr_phy62x2.py 08.12.2024 pvvx #
|
||||
|
||||
import serial
|
||||
import time
|
||||
|
|
@ -22,9 +22,9 @@ PHY_FLASH_SECTOR_SIZE = 4096
|
|||
PHY_FLASH_SECTOR_MASK = 0xfffff000
|
||||
PHY_WR_BLK_SIZE = 0x2000
|
||||
|
||||
__progname__ = 'PHY62x2 Utility'
|
||||
__progname__ = 'PHY62x2/ST17H66B Utility'
|
||||
__filename__ = 'rdwr_phy62x2.py'
|
||||
__version__ = "11.03.24"
|
||||
__version__ = "08.12.24"
|
||||
|
||||
def ParseHexFile(hexfile):
|
||||
try:
|
||||
|
|
@ -224,10 +224,12 @@ class phyflasher:
|
|||
self._port.flushOutput()
|
||||
self._port.flushInput()
|
||||
time.sleep(0.1)
|
||||
print('PHY62x2: Release RST_N if RTS is not connected...')
|
||||
print('ST17H66B: Turn on the power...')
|
||||
self._port.setDTR(False) #TM (hi)
|
||||
self._port.setRTS(False) #RSTN (hi)
|
||||
self._port.timeout = 0.04
|
||||
ttcl = 50
|
||||
ttcl = 250
|
||||
fct_mode = False
|
||||
pkt = 'UXTDWU' # UXTL16 UDLL48 UXTDWU
|
||||
while ttcl > 0:
|
||||
|
|
@ -240,11 +242,11 @@ class phyflasher:
|
|||
break
|
||||
ttcl = ttcl - 1
|
||||
if ttcl < 1:
|
||||
print('PHY62x2 - Error Reset!')
|
||||
print('Chip Reset error! Response: %s' % read)
|
||||
print('Check connection TX->RX, RX<-TX, RTS->RESET and Chip Power!')
|
||||
self._port.close()
|
||||
exit(4)
|
||||
print('PHY62x2 - Reset Ok')
|
||||
print('Chip Reset Ok. Response: %s' % read)
|
||||
self._port.baudrate = DEF_RUN_BAUD
|
||||
self._port.timeout = 0.2
|
||||
if fct_mode:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# rdwr_phy62x2.py 11.01.2024 pvvx #
|
||||
# rdwr_phy62x2.py 08.12.2024 pvvx #
|
||||
|
||||
import serial
|
||||
import time
|
||||
|
|
@ -22,9 +22,9 @@ PHY_FLASH_SECTOR_SIZE = 4096
|
|||
PHY_FLASH_SECTOR_MASK = 0xfffff000
|
||||
PHY_WR_BLK_SIZE = 0x2000
|
||||
|
||||
__progname__ = 'PHY62x2 Utility'
|
||||
__progname__ = 'PHY62x2/ST17H66B Utility'
|
||||
__filename__ = 'rdwr_phy62x2.py'
|
||||
__version__ = "11.03.24"
|
||||
__version__ = "08.12.24"
|
||||
|
||||
def ParseHexFile(hexfile):
|
||||
try:
|
||||
|
|
@ -224,10 +224,12 @@ class phyflasher:
|
|||
self._port.flushOutput()
|
||||
self._port.flushInput()
|
||||
time.sleep(0.1)
|
||||
print('PHY62x2: Release RST_N if RTS is not connected...')
|
||||
print('ST17H66B: Turn on the power...')
|
||||
self._port.setDTR(False) #TM (hi)
|
||||
self._port.setRTS(False) #RSTN (hi)
|
||||
self._port.timeout = 0.04
|
||||
ttcl = 50
|
||||
ttcl = 250
|
||||
fct_mode = False
|
||||
pkt = 'UXTDWU' # UXTL16 UDLL48 UXTDWU
|
||||
while ttcl > 0:
|
||||
|
|
@ -240,11 +242,11 @@ class phyflasher:
|
|||
break
|
||||
ttcl = ttcl - 1
|
||||
if ttcl < 1:
|
||||
print('PHY62x2 - Error Reset!')
|
||||
print('Chip Reset error! Response: %s' % read)
|
||||
print('Check connection TX->RX, RX<-TX, RTS->RESET and Chip Power!')
|
||||
self._port.close()
|
||||
exit(4)
|
||||
print('PHY62x2 - Reset Ok')
|
||||
print('Chip Reset Ok. Response: %s' % read)
|
||||
self._port.baudrate = DEF_RUN_BAUD
|
||||
self._port.timeout = 0.2
|
||||
if fct_mode:
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2
wr_key2.cmd
Normal file
2
wr_key2.cmd
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
python3 rdwr_phy62x2.py -p COM5 -e -r wh ./bin/BOOT_KEY2_v20.hex
|
||||
@rem python3 rdwr_phy62x2.py -p COM5 -r we 0x10000 ./bin/KEY_v20.bin
|
||||
Loading…
Add table
Add a link
Reference in a new issue