Добавлен TH05F. Коррекция хода RTC.

This commit is contained in:
pvvx 2024-02-23 15:34:55 +03:00
parent 565de1a2bb
commit 5487ab4345
50 changed files with 50297 additions and 26322 deletions

View file

@ -1,24 +1,24 @@
# BTHome THB1, THB2, BTH01, TH05(HW: v1.3..1.6)
# BTHome THB1, THB2, BTH01, TH05(HW: v1.3..1.6), TH05F
Custom firmware for Tuya devices on the PHY622x2 chipset
| [THB1](https://pvvx.github.io/THB1) | [THB2](https://pvvx.github.io/THB2) | [BTH01](https://pvvx.github.io/BTH01/) | [TH05_V1.3](https://pvvx.github.io/TH05-v1.3) | [TH05_V1.4](https://pvvx.github.io/TH-05) |
|:---:|:---:|:---:|:---:|:---:|
| ![THB1](https://pvvx.github.io/THB1/img/THB1.jpg) | ![THB2](https://pvvx.github.io/THB2/img/THB2.jpg) | ![BTH01](https://pvvx.github.io/BTH01/img/BTH01.jpg) | ![TH05V1.3](https://pvvx.github.io/TH05-v1.3/img/TH05-V1.3.jpg) | ![TH05V1.4](https://pvvx.github.io/TH-05/img/TH05V14.jpg) |
| [THB1](https://pvvx.github.io/THB1) | [THB2](https://pvvx.github.io/THB2) | [BTH01](https://pvvx.github.io/BTH01/) | [TH05_V1.3](https://pvvx.github.io/TH05-v1.3) | [TH05_V1.4](https://pvvx.github.io/TH-05) | [TH05F](https://pvvx.github.io/TH05F) |
|:---:|:---:|:---:|:---:|:---:|:---:|
| ![THB1](https://pvvx.github.io/THB1/img/THB1.jpg) | ![THB2](https://pvvx.github.io/THB2/img/THB2.jpg) | ![BTH01](https://pvvx.github.io/BTH01/img/BTH01.jpg) | ![TH05V1.3](https://pvvx.github.io/TH05-v1.3/img/TH05-V1.3.jpg) | ![TH05V1.4](https://pvvx.github.io/TH-05/img/TH05V14.jpg) | ![TH05F](https://pvvx.github.io/TH05F/img/TH05F.jpg)
* Программа для настройки и BLE OTA [PHY62x2BTHome.html](https://pvvx.github.io/THB2/web/PHY62x2BTHome.html)
## Прошивки Boot-OTA:
## Прошивки Boot и APP:
* Прошивки [Boot-OTA](https://github.com/pvvx/THB2/issues/10) имеет минимум функций. Boot-OTA используются только для выполнения OTA - для загрузки полнофункциональной версии APP (Application - файлы *.bin).
* Прошивка [Boot](https://github.com/pvvx/THB2/issues/10) имеет минимум функций. Boot используются только для выполнения OTA - для загрузки полнофункциональной версии APP (Application - файлы *.bin).
* Внешне отличить тип устройства возможно по символу смайлика на экране.
THB2 - файл bin\BOOT_THB2_v13.hex
BTH01 - файл bin\BOOT_BTH01_v13.hex
TH05 - файл bin\BOOT_TH05_v13.hex для версий указанных на печатной плате: [TH05_V1.4](https://pvvx.github.io/TH-05), TH05_V1.5, TH05_V1.6 с чипом BL55028
TH05V13 - файл bin\BOOT_TH05V13_v13.hex для [TH05_V1.3](https://pvvx.github.io/TH05-v1.3) с чипом BL55072
THB1 - файл bin\BOOT_BTH1_v13.hex
| Устройство | Файл Boot | Файл OTA | Маркировка на печатной плате |
|:---:|:---:|:---:|
| [THB1](https://pvvx.github.io/THB1) | BOOT_THB1_v14.hex | THB1_v14.bin | нет |
| [THB2](https://pvvx.github.io/THB2) | BOOT_THB2_v14.hex | THB2_v14.bin | нет |
| [BTH01](https://pvvx.github.io/BTH01) | BOOT_BTH01_v14.hex | BTH01_v14.bin | нет |
| [TH05_V1.4](https://pvvx.github.io/TH-05) | BOOT_TH05_v14.hex | TH05_v1.4.bin | TH05_V1.4, TH05_V1.5, TH05_V1.6 с чипом BL55028 |
| [TH05_V1.3](https://pvvx.github.io/TH05-v1.3) | BOOT_TH05D_v14.hex | TH05D_v14.bin | RSH-TH05-V1.3 с чипом BL55072 |
| [TH05F](https://pvvx.github.io/TH05F) | BOOT_TH05F_v14.hex | TH05F_v14.bin | TH05Y_V1.1, TH05Y_V1.2 с чипом QD01 2332 NT |
## Основные характеристики:
@ -43,8 +43,7 @@ THB1 - файл bin\BOOT_BTH1_v13.hex
| 1.1 | Добавлен триггер - вывод TX2 срабатывающий по установленным значениям температуры и/или влажности с гистерезисами. Передача состояния вывода RX2 при connect. Для термометров с экраном добавлен показ смайлика с "комфортом". Дополнены: изменение имени и MAC устройства. |
| 1.2 | Обработка и передача событий open/close со счетчиком с вывода маркированного "RX2" (для THB2 - "RX1"). |
| 1.3 | Добавлен THB1 и TH05V1.3. Следующий этап уменьшения потребления для версий с LCD дисплеем и опция отключения дисплея. |
| 1.4Beta | Стабилизация соединения для всех вариантов устройств. |
| 1.4 | Стабилизация соединения для всех вариантов устройств. Добавлен [TH05F](https://pvvx.github.io/TH05F). Коррекция хода RTC. |
## Прошивка:

File diff suppressed because it is too large Load diff

2977
bin/BOOT_TH05D_v14.hex Normal file

File diff suppressed because it is too large Load diff

2974
bin/BOOT_TH05F_v14.hex Normal file

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/TH05D_v14.bin Normal file

Binary file not shown.

BIN
bin/TH05F_v14.bin Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -98,6 +98,7 @@
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs.424614369" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs" valueType="definedSymbols">
<listOptionValue builtIn="false" value="USE_ROMSYM_ALIAS=1"/>
<listOptionValue builtIn="false" value="__GCC"/>
<listOptionValue builtIn="false" value="CLK_16M_ONLY=1"/>
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.598587326" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
</tool>
@ -164,6 +165,7 @@
<listOptionValue builtIn="false" value="CENTRAL_CFG=0x08"/>
<listOptionValue builtIn="false" value="USE_ROMSYM_ALIAS=1"/>
<listOptionValue builtIn="false" value="__GCC"/>
<listOptionValue builtIn="false" value="CLK_16M_ONLY=1"/>
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.1659095882" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
</tool>
@ -230,6 +232,7 @@
<listOptionValue builtIn="false" value="CENTRAL_CFG=0x08"/>
<listOptionValue builtIn="false" value="USE_ROMSYM_ALIAS=1"/>
<listOptionValue builtIn="false" value="__GCC"/>
<listOptionValue builtIn="false" value="CLK_16M_ONLY=1"/>
</option>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input.1110288971" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input"/>
</tool>
@ -338,6 +341,14 @@
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="flash_ota" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>${cross_make}</buildCommand>
<buildArguments>-j24</buildArguments>
<buildTarget>flash_ota</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
</cproject>

View file

@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser" keep-relative-paths="false" name="CDT GCC Build Output Parser" parameter="([^/\\\\]*)((g?cc)|([gc]\+\+)|(clang))" prefer-non-shared="true"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="212728091224071331" id="org.eclipse.embedcdt.managedbuild.cross.arm.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Arm Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1374827689994892801" id="org.eclipse.embedcdt.managedbuild.cross.arm.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Arm Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

View file

@ -24,7 +24,8 @@ SRC_PRJ += thb2_peripheral.c
SRC_PRJ += thservice.c
SRC_PRJ += flash_eep.c
SRC_PRJ += lcd_th05.c
SRC_PRJ += lcd_th05v13.c
SRC_PRJ += lcd_th05d.c
SRC_PRJ += lcd_th05f.c
SRC_PRJ += lcd_thb1.c
SRC_PRJ += ble_ota.c
SRC_PRJ += logger.c

View file

@ -130,12 +130,13 @@ void hal_rtc_clock_config(CLK32K_e clk32Mode)
}
/* Step 625 us */
uint32_t hal_systick(void)
{
return osal_sys_tick;
}
/* Step 625 us */
uint32_t hal_ms_intv(uint32_t tick)
{
uint32_t diff = 0;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -5660,8 +5660,6 @@ void config_RTC1(uint32 time)
@return None.
*/
uint32 sleep_total;
extern uint32 g_stack;
#ifdef __GNUC__
// Indicate that the specified function does not need prologue/epilogue sequences
// generated by the compiler. And function doesn't return.
@ -5670,6 +5668,7 @@ void wakeupProcess1(void) __attribute__ ((naked));
void wakeupProcess1(void)
{
uint32 current_RTC_tick;
uint32 sleep_total;
uint32 wakeup_time, wakeup_time0, next_time;
uint32 dlt_tick;
//restore initial_sp according to the app_initial_sp : 20180706 ZQ
@ -5832,6 +5831,7 @@ void wakeupProcess1(void)
g_llSleepContext.isTimer4RecoverRequired = FALSE;
}
#ifdef STACK_MAX_SRAM
extern uint32 g_stack;
__set_MSP((uint32_t)(&g_stack));
#endif
// app could add operation after wakeup

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -22,12 +22,19 @@
@if not exist "build\TH05%SWVER%.hex" goto :error
@copy "build\TH05%SWVER%.bin" .\bin
@
@del /Q "build\TH05V13%SWVER%.hex"
@del /Q "build\TH05V13%SWVER%.bin"
@del /Q "build\TH05D%SWVER%.hex"
@del /Q "build\TH05D%SWVER%.bin"
@make -s clean
@make -s -j PROJECT_NAME=TH05V13%SWVER% POJECT_DEF="-DDEVICE=DEVICE_TH05V13"
@if not exist "build\TH05V13%SWVER%.hex" goto :error
@copy "build\TH05V13%SWVER%.bin" .\bin
@make -s -j PROJECT_NAME=TH05D%SWVER% POJECT_DEF="-DDEVICE=DEVICE_TH05D"
@if not exist "build\TH05D%SWVER%.hex" goto :error
@copy "build\TH05D%SWVER%.bin" .\bin
@
@del /Q "build\TH05F%SWVER%.hex"
@del /Q "build\TH05F%SWVER%.bin"
@make -s clean
@make -s -j PROJECT_NAME=TH05F%SWVER% POJECT_DEF="-DDEVICE=DEVICE_TH05F"
@if not exist "build\TH05F%SWVER%.hex" goto :error
@copy "build\TH05F%SWVER%.bin" .\bin
@
@del /Q "build\THB1%SWVER%.hex"
@del /Q "build\THB1%SWVER%.bin"
@ -54,11 +61,17 @@
@if not exist "build\BOOT_TH05%SWVER%.hex" goto :error
@copy "build\BOOT_TH05%SWVER%.hex" .\bin
@
@del /Q "build\BOOT_TH05V13%SWVER%.hex"
@del /Q "build\BOOT_TH05D%SWVER%.hex"
@make -s clean
@make -s -j PROJECT_NAME=BOOT_TH05V13%SWVER% BOOT_OTA=1 POJECT_DEF="-DDEVICE=DEVICE_TH05V13"
@if not exist "build\BOOT_TH05V13%SWVER%.hex" goto :error
@copy "build\BOOT_TH05V13%SWVER%.hex" .\bin
@make -s -j PROJECT_NAME=BOOT_TH05D%SWVER% BOOT_OTA=1 POJECT_DEF="-DDEVICE=DEVICE_TH05D"
@if not exist "build\BOOT_TH05D%SWVER%.hex" goto :error
@copy "build\BOOT_TH05D%SWVER%.hex" .\bin
@
@del /Q "build\BOOT_TH05F%SWVER%.hex"
@make -s clean
@make -s -j PROJECT_NAME=BOOT_TH05F%SWVER% BOOT_OTA=1 POJECT_DEF="-DDEVICE=DEVICE_TH05F"
@if not exist "build\BOOT_TH05F%SWVER%.hex" goto :error
@copy "build\BOOT_TH05F%SWVER%.hex" .\bin
@
@del /Q "build\BOOT_THB1%SWVER%.hex"
@make -s clean

View file

@ -208,9 +208,11 @@ int cmd_parser(uint8_t * obuf, uint8_t * ibuf, uint32_t len) {
if (--len > sizeof(display_buff))
len = sizeof(display_buff);
if (len) {
wrk.lcd_ext_chow = 1;
memcpy(display_buff, &ibuf[1], len);
update_lcd();
}
} else
wrk.lcd_ext_chow = 0;
memcpy(&obuf[1], display_buff, sizeof(display_buff));
olen = 1 + sizeof(display_buff);
#endif

View file

@ -57,6 +57,47 @@ const cfg_t def_cfg = {
.averaging_measurements = 180 // 180*10 = 1800 sec, 30 min
};
#if 1
extern uint32_t g_counter_traking_avg;
void restore_utc_time_sec(void) {
if(clkt.utc_set_time_sec == 0) {
clkt.utc_time_add = AP_AON->SLEEP_R[2] + 0x10000; // + 65.536 ms
clkt.utc_time_sec = AP_AON->SLEEP_R[3];
}
clkt.utc_time_tik = clock_time_rtc();
}
uint32_t get_utc_time_sec(void) {
uint32_t new_time_tik, delta;
#if TEST_RTC_DELTA
do {
new_time_tik = AP_AON->RTCCNT;
} while(new_time_tik != AP_AON->RTCCNT);
#else
new_time_tik = AP_AON->RTCCNT;
#endif
if(new_time_tik <= clkt.utc_time_tik)
delta = new_time_tik - clkt.utc_time_tik;
else
delta = 0xffffffff - clkt.utc_time_tik + new_time_tik;
clkt.utc_time_tik = new_time_tik;
delta &= 0x1fffff; // 64 sec max
// delta in us
delta = ((((delta & 0xffff0000) >> 16) * g_counter_traking_avg) << 8)
+ (((delta & 0xffff) * g_counter_traking_avg) >> 8);
clkt.utc_time_add += delta;
while(clkt.utc_time_add > 1000000) {
clkt.utc_time_add -= 1000000;
clkt.utc_time_sec++;
}
AP_AON->SLEEP_R[2] = clkt.utc_time_add; // сохранить для восстановления часов после перезагрузки
AP_AON->SLEEP_R[3] = clkt.utc_time_sec; // сохранить для восстановления часов после перезагрузки
return clkt.utc_time_sec;
}
#else
void restore_utc_time_sec(void) {
if(clkt.utc_set_time_sec == 0) {
clkt.utc_time_add = (AP_AON->SLEEP_R[2] &((1<<15) - 1)) + 10;
@ -81,7 +122,7 @@ uint32_t get_utc_time_sec(void) {
else
clkt.utc_time_add += 0xffffffff - clkt.utc_time_tik + new_time_tik;
clkt.utc_time_tik = new_time_tik;
clkt.utc_time_sec += clkt.utc_time_add >> 15; // div 32768
clkt.utc_time_sec += (clkt.utc_time_add >> 15) * counter_tracking; // div 32768
clkt.utc_time_add &= (1<<15) - 1;
AP_AON->SLEEP_R[2] = clkt.utc_time_add; // сохранить для восстановления часов после перезагрузки
AP_AON->SLEEP_R[3] = clkt.utc_time_sec; // сохранить для восстановления часов после перезагрузки
@ -91,6 +132,7 @@ uint32_t get_utc_time_sec(void) {
#endif
return clkt.utc_time_sec;
}
#endif
void test_config(void) {
if (cfg.rf_tx_power > RF_PHY_TX_POWER_EXTRA_MAX)

View file

@ -38,12 +38,13 @@
*/
#define DEVICE_THB2 19
#define DEVICE_BTH01 20
#define DEVICE_TH05 21
#define DEVICE_TH05 21 // TH05_V1.4..1.6
#define DEVICE_THB1 23
#define DEVICE_TH05V13 24
#define DEVICE_TH05D 24 // TH05_V1.3
#define DEVICE_TH05F 25 // TH05Y_V1.2
#ifndef DEVICE
#define DEVICE DEVICE_TH05V13
#define DEVICE DEVICE_TH05F
#endif
// supported services by the device (bits)
@ -109,7 +110,7 @@
#define GPIO_INP GPIO_P10 // RX
#define DEF_MODEL_NUMBER_STR "THB2"
#define DEF_HARDWARE_REVISION "0001"
#define DEF_HARDWARE_REVISION "0013"
#define DEF_MANUFACTURE_NAME_STR "Tuya"
#elif DEVICE == DEVICE_BTH01
@ -145,11 +146,11 @@
#define GPIO_INP GPIO_P18 // mark RX2
#define DEF_MODEL_NUMBER_STR "BTH01"
#define DEF_HARDWARE_REVISION "0001"
#define DEF_HARDWARE_REVISION "0014"
#define DEF_MANUFACTURE_NAME_STR "Tuya"
#elif DEVICE == DEVICE_TH05
/* Model: TH05 */
/* Model: TH05 v1.3*/
#if OTA_TYPE == OTA_TYPE_BOOT
#define DEV_SERVICES (OTA_TYPE \
| SERVICE_SCREEN \
@ -167,10 +168,6 @@
)
#endif
#if ((DEV_SERVICES & SERVICE_THS) == 0) && (DEV_SERVICES & SERVICE_TH_TRG)
#error "Not SERVICE_TH_TRG!"
#endif
#define ADC_PIN_USE_OUT 1 // hal_gpio_write(ADC_PIN, 1);
#define ADC_PIN GPIO_P11
#define ADC_VBAT_CHL VBAT_ADC_P11
@ -196,7 +193,7 @@
//#define LED_OFF 0
#define DEF_MODEL_NUMBER_STR "TH05"
#define DEF_HARDWARE_REVISION "0014"
#define DEF_HARDWARE_REVISION "0015"
#define DEF_MANUFACTURE_NAME_STR "Tuya"
#elif DEVICE == DEVICE_THB1
@ -218,10 +215,6 @@
)
#endif
#if ((DEV_SERVICES & SERVICE_THS) == 0) && (DEV_SERVICES & SERVICE_TH_TRG)
#error "Not SERVICE_TH_TRG!"
#endif
#define ADC_PIN_USE_OUT 1 // нет подключения к +Vbat
#define ADC_PIN GPIO_P14
#define ADC_VBAT_CHL VBAT_ADC_P14
@ -244,8 +237,8 @@
#define DEF_HARDWARE_REVISION "0017"
#define DEF_MANUFACTURE_NAME_STR "Tuya"
#elif DEVICE == DEVICE_TH05V13
/* Model: TH05 v1.2 */
#elif DEVICE == DEVICE_TH05D
/* Model: TH05 v1.3 */
#if OTA_TYPE == OTA_TYPE_BOOT
#define DEV_SERVICES (OTA_TYPE \
| SERVICE_SCREEN \
@ -263,10 +256,6 @@
)
#endif
#if ((DEV_SERVICES & SERVICE_THS) == 0) && (DEV_SERVICES & SERVICE_TH_TRG)
#error "Not SERVICE_TH_TRG!"
#endif
//#define GPIO_LED GPIO_P00 // не припаян
//#define LED_ON 1
//#define LED_OFF 0
@ -289,14 +278,65 @@
#define GPIO_TRG GPIO_P09 // mark TX
#define GPIO_INP GPIO_P10 // mark RX
#define DEF_MODEL_NUMBER_STR "TH05"
#define DEF_MODEL_NUMBER_STR "TH05C"
#define DEF_HARDWARE_REVISION "0018"
#define DEF_MANUFACTURE_NAME_STR "Tuya"
#elif DEVICE == DEVICE_TH05F
/* Model: TH05Y_V1.2/1.2 */
#if OTA_TYPE == OTA_TYPE_BOOT
#define DEV_SERVICES (OTA_TYPE \
| SERVICE_SCREEN \
| SERVICE_THS \
| SERVICE_KEY \
)
#else
#define DEV_SERVICES (OTA_TYPE \
| SERVICE_SCREEN \
| SERVICE_THS \
| SERVICE_KEY \
| SERVICE_HISTORY \
| SERVICE_TH_TRG \
| SERVICE_RDS \
)
#endif
//#define GPIO_LED GPIO_P15 // не припаян
//#define LED_ON 1
//#define LED_OFF 0
#define ADC_PIN_USE_OUT 1 // нет подключения к +Vbat
#define ADC_PIN GPIO_P11
#define ADC_VBAT_CHL VBAT_ADC_P11
#define USE_TH_SENSOR 1
#define USE_SECREEN 1
#define I2C_SDA GPIO_P33 // SDA
#define I2C_SCL GPIO_P34 // SCL
#define I2C_LCD_SDA GPIO_P26 // SDA
#define I2C_LCD_SCL GPIO_P31 // SCL
#define GPIO_SPWR GPIO_P00 // питание сенсора
#define GPIO_KEY GPIO_P14
#define GPIO_LPWR GPIO_P02 // питание LCD драйвера
#define GPIO_TRG GPIO_P20 // mark TX2
#define GPIO_INP GPIO_P18 // mark RX2
#define DEF_MODEL_NUMBER_STR "TH05F"
#define DEF_HARDWARE_REVISION "0019"
#define DEF_MANUFACTURE_NAME_STR "Tuya"
#else
#error "DEVICE Not released!"
#endif
#if ((DEV_SERVICES & SERVICE_THS) == 0) && (DEV_SERVICES & SERVICE_TH_TRG)
#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
@ -351,6 +391,7 @@ typedef struct _work_parm_t {
#if (DEV_SERVICES & SERVICE_SCREEN)
uint8_t lcd_count;
#endif
uint8_t lcd_ext_chow; // показ TH/Clock отключен
uint8_t reboot; // reboot on disconnect, записывается в [OTA_MODE_SELECT_REG]
uint8_t boot_flg; // байт из [OTA_MODE_SELECT_REG]
} work_parm_t;

View file

@ -8,6 +8,9 @@
#ifndef _LCD_TH05_H_
#define _LCD_TH05_H_
#include "config.h"
#if (DEV_SERVICES & SERVICE_SCREEN)
/*
* TH-05 v1.3 LCD buffer: byte.bit
--7.7-- --6.7-- --4.3--
@ -58,6 +61,32 @@
None: 3.1, 3.3
*/
/*
* THB05F LCD buffer: byte.bit
--0.4-- --1.4-- --2.4-- BAT
| | | | | | | 3.5
| 0.5 0.0 1.5 1.0 2.5 2.0
| | | | | | | o 3.6
0.3 --0.1-- --1.1-- --2.1-- +--- 3.6
| | | | | | | 3.6|
| 0.6 0.2 1.6 1.2 2.6 2.2 ---- 3.7
| | | | | | | 3.6|
--0.7-- --1.7-- * --2.7-- ---- 2.3
1.3
--4.4-- --5.4--
| | | | ooo
3.0 3.0 4.5 4.0 5.5 5.0 4.3
/ \ / \ | | | |
3.4( \_/ 3.1 \_/ )3.4 --4.1-- --5.1--
3.1 / \ 3.1 | | | |
\_/ 4.6 4.2 5.6 5.2 %
3.0 | | | | 5.3
--4.7-- --5.7--
None:
*/
/*
* THB1 LCD buffer: byte.bit
@ -81,15 +110,19 @@
6.6 | | | | 5.7
--4.3-- --5.3--
OO 1.7
None:
*/
#if (DEVICE == DEVICE_THB1)
#define LCD_BUF_SIZE 7
#elif (DEVICE == DEVICE_TH05V13)
#elif (DEVICE == DEVICE_TH05D)
#define LCD_BUF_SIZE 8
#else
#elif (DEVICE == DEVICE_TH05)
#define LCD_BUF_SIZE 6
#elif (DEVICE == DEVICE_TH05F)
#define LCD_BUF_SIZE 6
#else
#error "DEVICE Not released!"
#endif
extern uint8_t lcd_i2c_addr; // LCD controller I2C address
@ -146,4 +179,5 @@ void chow_lcd(int flg);
void lcd_show_version(void);
extern void send_to_lcd(uint8_t *pbuf, int len);
#endif // (DEV_SERVICES & SERVICE_SCREEN)
#endif /* _LCD_TH05_H_ */

View file

@ -64,7 +64,7 @@ uint8_t 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];
uint8_t display_out_buff[LCD_BUF_SIZE+1] = { 0 };
const uint8_t lcd_init_cmd[] = {
// LCD controller initialize:

View file

@ -7,7 +7,7 @@
#include <string.h>
#include "types.h"
#include "config.h"
#if (DEV_SERVICES & SERVICE_SCREEN) && (DEVICE == DEVICE_TH05V13)
#if (DEV_SERVICES & SERVICE_SCREEN) && (DEVICE == DEVICE_TH05D)
#include "OSAL.h"
#include "gpio.h"
#include "rom_sym_def.h"
@ -128,7 +128,7 @@ uint8_t lcd_i2c_addr; // = 0x3E
uint8_t display_buff[LCD_BUF_SIZE] = {
0, LCD_SYM12_o, LCD_SYM12_o, 0
};
uint8_t display_out_buff[LCD_BUF_SIZE+1];
uint8_t display_out_buff[LCD_BUF_SIZE+1] = { 0 };
const uint8_t lcd_init_cmd[] = {
// LCD controller initialize:

View file

@ -0,0 +1,337 @@
/*
* lcd_th05.c
*
* Created on: 23 янв. 2024 г.
* Author: pvvx, Shestoperd
*/
#include <string.h>
#include "types.h"
#include "config.h"
#if (DEV_SERVICES & SERVICE_SCREEN) && (DEVICE == DEVICE_TH05F)
#include "OSAL.h"
#include "gpio.h"
#include "clock.h"
#include "rom_sym_def.h"
#include "dev_i2c.h"
#include "sensors.h"
#include "lcd.h"
#include "thb2_peripheral.h"
#define LCD_I2C_ADDR 0x3E
#define I2C_WAIT_ms 1
dev_i2c_t i2c_dev1 = {
//.pi2cdev = AP_I2C1,
.scl = I2C_LCD_SCL,
.sda = I2C_LCD_SDA,
.speed = I2C_100KHZ,
.i2c_num = 0
};
uint8_t lcd_i2c_addr; // = 0x3E
/* 0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F*/
const uint8_t display_numbers[] = {
// 76543210
0b011110101, // 0
0b000000101, // 1
0b011010011, // 2
0b010010111, // 3
0b000100111, // 4
0b010110110, // 5
0b011110110, // 6
0b000010101, // 7
0b011110111, // 8
0b010110111, // 9
0b001110111, // A
0b011100110, // b
0b011110000, // C
0b011000111, // d
0b011110010, // E
0b001110010 // F
};
// 76543210
#define LCD_SYM_b 0b011100110 // "b"
#define LCD_SYM_H 0b001100111 // "H"
#define LCD_SYM_h 0b001100110 // "h"
#define LCD_SYM_i 0b001000000 // "i"
#define LCD_SYM_L 0b011100000 // "L"
#define LCD_SYM_o 0b011000110 // "o"
#define LCD_SYM_t 0b011100010 // "t"
#define LCD_SYM_0 0b011110101 // "0"
#define LCD_SYM_A 0b001110111 // "A"
#define LCD_SYM_a 0b011110110 // "a"
#define LCD_SYM_P 0b001110011 // "P"
uint8_t display_buff[LCD_BUF_SIZE] = {
0, LCD_SYM_o, LCD_SYM_o, 0
};
uint8_t display_out_buff[LCD_BUF_SIZE+1] = { 8, 0 };
const uint8_t lcd_init_cmd[] = {
// LCD controller initialize:
0xea, // Set IC Operation(ICSET): Software Reset, Internal oscillator circuit
0xd8, // Mode Set (MODE SET): Display enable, 1/3 Bias, power saving
0xbc, // Display control (DISCTL): Power save mode 3, FRAME flip, Power save mode 1
0x80, // load data pointer
0xf0, // blink control off, 0xf2 - blink
0xfc, // All pixel control (APCTL): Normal
0x60,
0x00,0x00,000,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
/* 0x0 = " "
* 0x1 = "°Г"
* 0x2 = " _"
* 0x3 = "°C"
* 0x4 = " -"
* 0x5 = "°F"
* 0x6 = " ="
* 0x7 = "°E" */
void show_temp_symbol(LCD_TEMP_SYMBOLS symbol) {
display_buff[2] &= ~BIT(3);
display_buff[3] &= ~(BIT(6) | BIT(7));
if(symbol & 1)
display_buff[3] |= BIT(6);
if(symbol & 2)
display_buff[2] |= BIT(3);
if(symbol & 4)
display_buff[3] |= BIT(7);
}
/* 0 = " " off,
* 1 = " ^_^ " happy
* 2 = " -^- " sad
* 3 = " ooo "
* 4 = "( )"
* 5 = "(^_^)" happy
* 6 = "(-^-)" sad
* 7 = "(ooo)" */
void show_smiley(LCD_SMILEY_SYMBOLS symbol) {
display_buff[3] &= ~(BIT(0) | BIT(1) | BIT(4));
if(symbol & 1)
display_buff[3] |= BIT(0);
if(symbol & 2)
display_buff[3] |= BIT(1);
if(symbol & 4)
display_buff[3] |= BIT(4);
}
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(5);
else
display_buff[3] &= ~BIT(5);
}
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_H; // "H"
display_buff[5] |= LCD_SYM_i; // "i"
} else if (number < -9) {
display_buff[4] |= LCD_SYM_L; // "L"
display_buff[5] |= LCD_SYM_o; // "o"
} 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];
}
}
void lcd_show_version(void) {
#if OTA_TYPE
display_buff[0] = LCD_SYM_b;
display_buff[1] = LCD_SYM_o;
display_buff[2] = LCD_SYM_t;
#else
display_buff[0] = LCD_SYM_A;
display_buff[1] = LCD_SYM_P;
display_buff[2] = LCD_SYM_P;
#endif
display_buff[3] &= BIT(5); // bat
display_buff[4] &= BIT(3); // connect
display_buff[4] |= display_numbers[(APP_VERSION >> 4) & 0x0f];
display_buff[5] = display_numbers[APP_VERSION & 0x0f];
update_lcd();
}
void chow_clock(void) {
uint32_t tmp = clkt.utc_time_sec / 60;
uint32_t min = tmp % 60;
uint32_t hrs = (tmp / 60) % 24;
display_buff[0] = 0;
display_buff[1] = display_numbers[(hrs / 10) % 10];
display_buff[2] = display_numbers[hrs % 10];
display_buff[3] &= BIT(5); // bat
display_buff[4] &= BIT(3); // connect
display_buff[4] |= display_numbers[(min / 10) % 10];
display_buff[5] = display_numbers[min % 10];
update_lcd();
}
static void chow_measure(void) {
#if (DEV_SERVICES & SERVICE_THS)
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(LCD_TSYMBOL_C);
#if (OTA_TYPE == OTA_TYPE_APP)
if(cfg.flg & FLG_SHOW_SMILEY) {
#if (DEV_SERVICES & SERVICE_TH_TRG)
if(cfg.flg & FLG_SHOW_TRG) {
if(measured_data.flg.comfort) {
if(measured_data.flg.trg_on)
show_smiley(LD_SSYMBOL_HAPPY);
else
show_smiley(LD_SSYMBOL__HAPPY);
} else {
if(measured_data.flg.trg_on)
show_smiley(LD_SSYMBOL_SAD);
else
show_smiley(LD_SSYMBOL__SAD);
}
} else
#endif // SERVICE_TH_TRG
{
if(measured_data.flg.comfort)
show_smiley(LD_SSYMBOL_HAPPY);
else
show_smiley(LD_SSYMBOL_SAD);
}
#if (DEV_SERVICES & SERVICE_TH_TRG)
} else if(cfg.flg & FLG_SHOW_TRG) {
if(measured_data.flg.trg_on)
show_smiley(LD_SSYMBOL_ALL);
else
show_smiley(LD_SSYMBOL_OFF);
} else
#endif // SERVICE_TH_TRG
#endif // OTA_TYPE
show_smiley(LD_SSYMBOL_OFF);
#else
show_big_number_x10(measured_data.battery_mv/100);
show_small_number((measured_data.battery > 99)? 99 : measured_data.battery, true);
show_battery_symbol(1);
show_smiley(LD_SSYMBOL_OFF);
#endif // SERVICE_THS
show_ble_symbol(gapRole_state == GAPROLE_CONNECTED);
update_lcd();
}
/* flg != 0 -> chow_measure */
void chow_lcd(int flg) {
if(wrk.lcd_ext_chow) // показ TH/Clock отключен
return;
#if OTA_TYPE == OTA_TYPE_BOOT
if(flg)
chow_measure();
#else
if(cfg.flg & FLG_SHOW_TIME) {
if(wrk.lcd_count++ & 1)
chow_clock();
else
chow_measure();
} else if(flg) {
chow_measure();
}
#endif
}
void send_to_lcd(uint8_t *pbuf, int len) {
if (lcd_i2c_addr) {
init_i2c(&i2c_dev1);
send_i2c_buf(&i2c_dev1, lcd_i2c_addr, pbuf, len);
deinit_i2c(&i2c_dev1);
}
}
void update_lcd(void) {
#if (OTA_TYPE == OTA_TYPE_APP)
if(lcd_i2c_addr == 0 || (cfg.flg & FLG_DISPLAY_OFF) != 0)
return;
#endif
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) {
i2c_dev1.speed = I2C_100KHZ;
#if (OTA_TYPE == OTA_TYPE_APP)
if(hal_gpio_read(GPIO_LPWR) == 0) {
hal_gpio_write(GPIO_LPWR, 1);
WaitMs(2);
}
#endif
init_i2c(&i2c_dev1);
if(!send_i2c_buf(&i2c_dev1, LCD_I2C_ADDR, (uint8_t *) lcd_init_cmd, sizeof(lcd_init_cmd))) {
#if (OTA_TYPE == OTA_TYPE_APP)
//display_out_buff[0] = 8;
if(cfg.flg & FLG_DISPLAY_OFF) {
send_i2c_byte(&i2c_dev1, LCD_I2C_ADDR, 0xd0); // Mode Set (MODE SET): Display disable, 1/3 Bias, power saving
deinit_i2c(&i2c_dev1);
hal_gpio_write(GPIO_LPWR, 0);
return;
}
#endif
lcd_i2c_addr = LCD_I2C_ADDR;
} else
lcd_i2c_addr = 0;
i2c_dev1.speed = I2C_400KHZ;
deinit_i2c(&i2c_dev1);
}
/****************************************************/
#endif // (DEV_SERVICES & SERVICE_SCREEN)

View file

@ -64,7 +64,7 @@ uint8_t 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];
uint8_t display_out_buff[LCD_BUF_SIZE+1] = { 0 };
/* blink off: display_out_buff[0] = 0xf0, on: display_out_buff[0] = 0xf2 */
const uint8_t lcd_init_cmd[] = {

View file

@ -142,7 +142,7 @@ const ioinit_cfg_t ioInit[] = {
{ GPIO_P33, GPIO_PULL_DOWN },
{ GPIO_P34, GPIO_PULL_DOWN }
#elif (DEVICE == DEVICE_BTH01)
{ GPIO_P00, GPIO_PULL_UP }, // GPIO_SPWR Sensor Vdd
{ GPIO_P00, GPIO_PULL_UP_S }, // GPIO_SPWR Sensor Vdd
{ GPIO_P01, GPIO_PULL_DOWN },
{ GPIO_P02, GPIO_PULL_DOWN },
{ GPIO_P03, GPIO_PULL_DOWN },
@ -174,7 +174,7 @@ const ioinit_cfg_t ioInit[] = {
{ GPIO_P33, GPIO_FLOATING }, // I2C_SDA
{ GPIO_P34, GPIO_FLOATING } // // I2C_SCL
#elif (DEVICE == DEVICE_TH05)
{ GPIO_P00, GPIO_PULL_UP }, // GPIO_SPWR Sensor Vdd
{ GPIO_P00, GPIO_PULL_UP_S }, // GPIO_SPWR Sensor Vdd
{ GPIO_P01, GPIO_PULL_DOWN },
{ GPIO_P02, GPIO_PULL_UP }, // GPIO_LPWR
{ GPIO_P03, GPIO_PULL_DOWN },
@ -226,16 +226,20 @@ const ioinit_cfg_t ioInit[] = {
{ GPIO_P24, GPIO_PULL_DOWN },
{ GPIO_P25, GPIO_PULL_DOWN },
{ GPIO_P26, GPIO_PULL_DOWN },
{ GPIO_P27, GPIO_PULL_DOWN },
// { GPIO_P27, GPIO_PULL_DOWN },
{ GPIO_P31, GPIO_PULL_DOWN },
{ GPIO_P32, GPIO_PULL_DOWN },
{ GPIO_P33, GPIO_PULL_UP }, // I2C_SDA CNV1972
{ GPIO_P34, GPIO_PULL_UP } // I2C_SCL CNV1972
#elif (DEVICE == DEVICE_TH05V13)
#elif (DEVICE == DEVICE_TH05D)
#ifdef GPIO_LED
{ GPIO_P00, GPIO_FLOATING }, // LED
#else
{ GPIO_P00, GPIO_PULL_DOWN }, // LED - не припаян R1 Q10 ...
#endif
{ GPIO_P01, GPIO_PULL_DOWN },
{ GPIO_P02, GPIO_PULL_UP }, // KEY - GPIO_KEY
{ GPIO_P03, GPIO_PULL_UP },
{ GPIO_P03, GPIO_PULL_DOWN },
{ GPIO_P07, GPIO_PULL_UP }, // CHT8305 Alert
#ifdef GPIO_TRG
{ GPIO_P09, GPIO_FLOATING }, // TX - GPIO_TRG
@ -254,11 +258,43 @@ const ioinit_cfg_t ioInit[] = {
{ GPIO_P24, GPIO_PULL_DOWN },
{ GPIO_P25, GPIO_PULL_DOWN },
{ GPIO_P26, GPIO_PULL_DOWN },
{ GPIO_P27, GPIO_PULL_DOWN },
// { GPIO_P27, GPIO_PULL_DOWN },
{ GPIO_P31, GPIO_FLOATING }, // CHT8305 SDA
{ GPIO_P32, GPIO_FLOATING }, // CHT8305 SCL
{ GPIO_P33, GPIO_PULL_DOWN },
{ GPIO_P34, GPIO_PULL_DOWN }
#elif (DEVICE == DEVICE_TH05F)
{ GPIO_P00, GPIO_PULL_UP_S }, // GPIO_SPWR Sensor Vdd
{ GPIO_P01, GPIO_PULL_DOWN },
{ GPIO_P02, GPIO_FLOATING }, // GPIO_LPWR питание LCD драйвера
{ GPIO_P03, GPIO_PULL_DOWN },
{ GPIO_P07, GPIO_PULL_DOWN },
{ GPIO_P09, GPIO_PULL_UP }, // TX
{ GPIO_P10, GPIO_PULL_UP }, // RX - GPIO_INP
{ GPIO_P11, GPIO_PULL_UP }, // назначен как ADC_PIN
{ GPIO_P14, GPIO_PULL_UP }, // KEY - GPIO_KEY
#ifdef GPIO_LED
{ GPIO_P15, GPIO_FLOATING }, // LED (R7/D1/GND)
#else
{ GPIO_P15, GPIO_PULL_UP }, // LED (R7/D1/GND)
#endif
{ GPIO_P16, GPIO_PULL_DOWN },
{ GPIO_P17, GPIO_PULL_DOWN },
{ GPIO_P18, GPIO_PULL_UP }, // RX2
#ifdef GPIO_TRG
{ GPIO_P20, GPIO_FLOATING }, // TX2 - GPIO_TRG
#else
{ GPIO_P20, GPIO_PULL_UP }, // TX2 - GPIO_TRG
#endif
{ GPIO_P23, GPIO_PULL_DOWN },
{ GPIO_P24, GPIO_PULL_DOWN },
{ GPIO_P25, GPIO_PULL_DOWN }, // mark "P25"
{ GPIO_P26, GPIO_FLOATING }, // LCD I2C SDA
// { GPIO_P27, GPIO_PULL_DOWN },
{ GPIO_P31, GPIO_FLOATING }, // LCD I2C SCL
{ GPIO_P32, GPIO_PULL_DOWN },
{ GPIO_P33, GPIO_FLOATING }, // CHT8305 SDA
{ GPIO_P34, GPIO_FLOATING } // CHT8305 SCL
#else
#error "DEVICE Not released!"
#endif

View file

@ -1,2 +0,0 @@
python3 rdwr_phy62x2.py -p COM11 -e -r wh ./bin/BOOT_TH05V13_v14.hex
@rem python3 rdwr_phy62x2.py -p COM11 -r we 0x10000 ./bin/TH05V13_v14.bin

2
wr_th05d.cmd Normal file
View file

@ -0,0 +1,2 @@
python3 rdwr_phy62x2.py -p COM11 -e -r wh ./bin/BOOT_TH05D_v14.hex
@rem python3 rdwr_phy62x2.py -p COM11 -r we 0x10000 ./bin/TH05VD_v14.bin

2
wr_th05f.cmd Normal file
View file

@ -0,0 +1,2 @@
python3 rdwr_phy62x2.py -p COM11 -e -r wh ./bin/BOOT_TH05F_v14.hex
@rem python3 rdwr_phy62x2.py -p COM11 -r we 0x10000 ./bin/TH05F_v14.bin