diff --git a/ATC_v42.bin b/ATC_v42.bin index e5ecd9c7..7a29316b 100644 Binary files a/ATC_v42.bin and b/ATC_v42.bin differ diff --git a/BTH_v42.bin b/BTH_v42.bin index e1e3e002..390c8055 100644 Binary files a/BTH_v42.bin and b/BTH_v42.bin differ diff --git a/CGDK2_v42.bin b/CGDK2_v42.bin index 3cde6d2f..a7a73994 100644 Binary files a/CGDK2_v42.bin and b/CGDK2_v42.bin differ diff --git a/CGDK2n_v42.bin b/CGDK2n_v42.bin deleted file mode 100644 index 499e2b02..00000000 Binary files a/CGDK2n_v42.bin and /dev/null differ diff --git a/CGG1M_v42.bin b/CGG1M_v42.bin index 05f25f24..413c6eac 100644 Binary files a/CGG1M_v42.bin and b/CGG1M_v42.bin differ diff --git a/CGG1_v42.bin b/CGG1_v42.bin index 8b1c2876..968b9416 100644 Binary files a/CGG1_v42.bin and b/CGG1_v42.bin differ diff --git a/MHO_C401N_v42.bin b/MHO_C401N_v42.bin index 69199e81..fc302550 100644 Binary files a/MHO_C401N_v42.bin and b/MHO_C401N_v42.bin differ diff --git a/MHO_C401_v42.bin b/MHO_C401_v42.bin index b2b36238..626b91f2 100644 Binary files a/MHO_C401_v42.bin and b/MHO_C401_v42.bin differ diff --git a/README.md b/README.md index 5d867eb3..8cd5e506 100644 --- a/README.md +++ b/README.md @@ -230,25 +230,60 @@ This requires the _Experimental Web Platform Features_ flag enabled in your brow ### Average power consumption -**Xiaomi Mijia (LYWSD03MMC)** +**Xiaomi Mijia (LYWSD03MMC B1.4)** Using the default settings for advertising interval of 2.5 seconds and measurement interval of 10 seconds: -* Bluetooth Advertisement: 14..20 uA 3.3V ([CR2032](https://pvvx.github.io/ATC_MiThermometer/CustPower.html) [over 6 months](https://github.com/pvvx/ATC_MiThermometer/issues/23#issuecomment-766898945)) -* Bluetooth Connection: 14..25 uA 3.3V (CR2032 over 6 months) +* Bluetooth Advertisement: 14..15 uA 3.3V ([CR2032](https://pvvx.github.io/ATC_MiThermometer/CustPower.html) [over 1 years](https://github.com/pvvx/ATC_MiThermometer/issues/23#issuecomment-766898945)) +* Bluetooth Connection: 14..25 uA 3.3V (CR2032 over 10 months) ![PowerAdvInt](https://github.com/pvvx/ATC_MiThermometer/blob/master/img/PowerAdvInt.gif) ![PowerLife.gif](https://github.com/pvvx/ATC_MiThermometer/blob/master/img/PowerLife.gif) +**Xiaomi Mijia (MJWSD05MMC)** + +Using the default settings for advertising interval of 5 seconds and measurement interval of 20 seconds: + +* Bluetooth Advertisement: 19..21 uA 3.3V (CR2450 over 2 years) +* Bluetooth Connection: 25..30 uA 3.3V (CR2450 over 1.5 years) + **Xiaomi Miaomiaoce (MHO-C401)** Using the default settings for advertising interval of 2.5 seconds and measurement interval of 20 seconds: -* Bluetooth Advertisement: 12..30 uA 3.3V ([depends on the amount of temperature or humidity changes over time to display](https://pvvx.github.io/MHO_C401/power_altfw.html)) +* Bluetooth Advertisement: 15..30 uA 3.3V ([depends on the amount of temperature or humidity changes over time to display](https://pvvx.github.io/MHO_C401/power_altfw.html)) * Bluetooth Connection: 15..30 uA 3.3V (depends on the amount of temperature or humidity changes over time to display) +**Xiaomi Miaomiaoce (MHO-C401N)** + +Using the default settings for advertising interval of 2.5 seconds and measurement interval of 20 seconds: + +* Bluetooth Advertisement: 10..14 uA 3.3V (depends on the amount of temperature or humidity changes over time to display) +* Bluetooth Connection: 13..17 uA 3.3V (depends on the amount of temperature or humidity changes over time to display) + +**Qingping (CGDK2)** + +Using the default settings for advertising interval of 2.5 seconds and measurement interval of 20 seconds: + +* Bluetooth Advertisement: 18..21 uA 3.3V +* Bluetooth Connection: 23..30 uA 3.3V + +**Qingping (CGG1)** + +Using the default settings for advertising interval of 2.5 seconds and measurement interval of 20 seconds: + +* Bluetooth Advertisement: 12..16 uA 3.3V +* Bluetooth Connection: 23..30 uA 3.3V + +**Qingping (CGG1N)** + +Using the default settings for advertising interval of 2.5 seconds and measurement interval of 10 seconds: + +* Bluetooth Advertisement: 12..16 uA 3.3V +* Bluetooth Connection: 23..30 uA 3.3V + ### Bluetooth Advertising Formats The Firmware can be configured to support one of four different Bluetooth advertisements data formats. Xiaomi, ATC, Custom, BTHome and encrypted options. diff --git a/SDK/components/drivers/8258/timer.h b/SDK/components/drivers/8258/timer.h index c683798f..2d66e086 100644 --- a/SDK/components/drivers/8258/timer.h +++ b/SDK/components/drivers/8258/timer.h @@ -57,7 +57,7 @@ typedef enum{ * @brief system Timer : 16Mhz, Constant */ enum{ - CLOCK_16M_SYS_TIMER_CLK_1S = 16*1000*1000, + CLOCK_16M_SYS_TIMER_CLK_1S = 16*1000*1000, CLOCK_16M_SYS_TIMER_CLK_1MS = 16*1000, CLOCK_16M_SYS_TIMER_CLK_1US = 16, }; diff --git a/src/app.c b/src/app.c index b3100476..975141cf 100644 --- a/src/app.c +++ b/src/app.c @@ -30,32 +30,20 @@ void app_enter_ota_mode(void); -RAM uint32_t chow_tick_clk; // count show validity time, in clock -RAM uint32_t chow_tick_sec; // count show validity time, in sec -RAM uint8_t show_stage; // count/stage update lcd code buffer -RAM lcd_flg_t lcd_flg; - RAM measured_data_t measured_data; -RAM volatile uint8_t tx_measures; - -RAM volatile uint8_t start_measure; // start measure all -RAM volatile uint8_t wrk_measure; -RAM volatile uint8_t end_measure; -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) -RAM volatile uint8_t lcd_update; -#else -RAM uint32_t min_step_time_update_lcd; // = cfg.min_step_time_update_lcd * 0.05 sec -RAM uint32_t tim_last_chow; // timer show lcd >= 1.5 sec -#endif -RAM uint32_t tim_measure; // timer measurements >= 10 sec +RAM volatile uint8_t tx_measures; // measurement transfer counter, flag +RAM volatile uint8_t start_measure; // start measurements +RAM volatile uint8_t wrk_measure; // measurements in process +RAM uint8_t end_measure; // measurements completed +RAM uint32_t tim_measure; // measurement timer RAM uint32_t adv_interval; // adv interval in 0.625 ms // = cfg.advertising_interval * 100 RAM uint32_t connection_timeout; // connection timeout in 10 ms, Tdefault = connection_latency_ms * 4 = 2000 * 4 = 8000 ms RAM uint32_t measurement_step_time; // = adv_interval * measure_interval RAM uint32_t utc_time_sec; // clock in sec (= 0 1970-01-01 00:00:00) -RAM uint32_t utc_time_sec_tick; +RAM uint32_t utc_time_sec_tick; // clock counter in 1/16 us #if USE_TIME_ADJUST RAM uint32_t utc_time_tick_step = CLOCK_16M_SYS_TIMER_CLK_1S; // adjust time clock (in 1/16 us for 1 sec) #else @@ -66,6 +54,10 @@ RAM int32_t rest_adv_int_tad; // timer event restore adv.intervals (in adv tik) RAM uint32_t key_pressed_tik, key_pressed_tiks; // timer key_pressed (in sys tik) #endif +#if BLE_SECURITY_ENABLE +RAM uint32_t pincode; +#endif + #if USE_SECURITY_BEACON RAM uint8_t bindkey[16]; #endif @@ -76,30 +68,24 @@ const scomfort_t def_cmf = { .h = {3000,6000} // x0.01 % }; -void lcd(void); - // Settings const cfg_t def_cfg = { .flg.temp_F_or_C = false, .flg.comfort_smiley = true, -#if DEVICE_TYPE != DEVICE_MJWSD05MMC - .flg.blinking_time_smile = false, - .flg.show_batt_enabled = false, - .flg2.smiley = 0, // 0 = " " off - .flg2.bt5phy = 1, // support BT5.0 -#endif - .flg.tx_measures = false, .flg.advertising_type = ADV_TYPE_DEFAULT, - .advertising_interval = 80, // multiply by 62.5 ms = 5 sec + .rf_tx_power = RF_POWER_P0p04dBm, // RF_POWER_P3p01dBm, + .connect_latency = DEF_CONNECT_LATENCY, // (49+1)*1.25*16 = 1000 ms #if DEVICE_TYPE == DEVICE_MJWSD05MMC - .flg.time_am_pm = true, + .advertising_interval = 80, // multiply by 62.5 ms = 5 sec .flg.comfort_smiley = true, - .measure_interval = 4, // * advertising_interval = 10 sec + .measure_interval = 4, // * advertising_interval = 20 sec .hw_cfg.hwver = HW_VER_MJWSD05MMC, #if USE_FLASH_MEMO - .averaging_measurements = 180, // * measure_interval = 10 * 180 = 1800 sec = 30 minutes + .averaging_measurements = 90, // * measure_interval = 20 * 90 = 1800 sec = 30 minutes #endif #elif DEVICE_TYPE == DEVICE_LYWSD03MMC + .flg2.adv_flags = true, + .advertising_interval = 40, // multiply by 62.5 ms = 2.5 sec .flg.comfort_smiley = true, .measure_interval = 4, // * advertising_interval = 10 sec .min_step_time_update_lcd = 49, //x0.05 sec, 2.45 sec @@ -108,6 +94,8 @@ const cfg_t def_cfg = { .averaging_measurements = 180, // * measure_interval = 10 * 180 = 1800 sec = 30 minutes #endif #elif DEVICE_TYPE == DEVICE_MHO_C401 + .flg2.adv_flags = true, + .advertising_interval = 40, // multiply by 62.5 ms = 2.5 sec .flg.comfort_smiley = true, .measure_interval = 8, // * advertising_interval = 20 sec .min_step_time_update_lcd = 99, //x0.05 sec, 4.95 sec @@ -116,15 +104,19 @@ const cfg_t def_cfg = { .averaging_measurements = 90, // * measure_interval = 20 * 90 = 1800 sec = 30 minutes #endif #elif DEVICE_TYPE == DEVICE_MHO_C401N + .flg2.adv_flags = true, + .advertising_interval = 40, // multiply by 62.5 ms = 2.5 sec .flg.comfort_smiley = true, .measure_interval = 8, // * advertising_interval = 20 sec - .min_step_time_update_lcd = 49, //x0.05 sec, 2.45 sec + .min_step_time_update_lcd = 99, //x0.05 sec, 4.95 sec .hw_cfg.hwver = HW_VER_MHO_C401_2022, #if USE_FLASH_MEMO .averaging_measurements = 90, // * measure_interval = 20 * 90 = 1800 sec = 30 minutes #endif #elif DEVICE_TYPE == DEVICE_CGG1 #if DEVICE_CGG1_ver == 2022 + .flg2.adv_flags = true, + .advertising_interval = 40, // multiply by 62.5 ms = 2.5 sec .flg.comfort_smiley = true, .measure_interval = 4, // * advertising_interval = 10 sec .min_step_time_update_lcd = 49, //x0.05 sec, 2.45 sec @@ -133,6 +125,8 @@ const cfg_t def_cfg = { .averaging_measurements = 180, // * measure_interval = 10 * 180 = 1800 sec = 30 minutes #endif #else + .flg2.adv_flags = true, + .advertising_interval = 40, // multiply by 62.5 ms = 2.5 sec .flg.comfort_smiley = true, .measure_interval = 8, // * advertising_interval = 20 sec .min_step_time_update_lcd = 99, //x0.05 sec, 4.95 sec @@ -142,6 +136,8 @@ const cfg_t def_cfg = { #endif #endif #elif DEVICE_TYPE == DEVICE_CGDK2 + .flg2.adv_flags = true, + .advertising_interval = 40, // multiply by 62.5 ms = 2.5 sec .flg.comfort_smiley = false, .measure_interval = 4, // * advertising_interval = 10 sec .min_step_time_update_lcd = 49, //x0.05 sec, 2.45 sec @@ -150,10 +146,9 @@ const cfg_t def_cfg = { .averaging_measurements = 180, // * measure_interval = 10 * 180 = 1800 sec = 30 minutes #endif #endif - .rf_tx_power = RF_POWER_P0p04dBm, // RF_POWER_P3p01dBm, - .connect_latency = DEF_CONNECT_LATENCY // (49+1)*1.25*16 = 1000 ms }; RAM cfg_t cfg; + static const external_data_t def_ext = { #if DEVICE_TYPE != DEVICE_MJWSD05MMC .big_number = 0, @@ -172,9 +167,16 @@ static const external_data_t def_ext = { #endif }; RAM external_data_t ext; -#if BLE_SECURITY_ENABLE -RAM uint32_t pincode; -#endif + +#if DEVICE_TYPE == DEVICE_LYWSD03MMC +/* 0 - LYWSD03MMC B1.4 + 3 - LYWSD03MMC B1.9 + 4 - LYWSD03MMC B1.6 + 5 - LYWSD03MMC B1.7 */ +static const uint8_t id2hwver[8] = { + '4','4','4','9','6','7','4','4' +}; +#endif // DEVICE_TYPE == DEVICE_LYWSD03MMC void set_hw_version(void) { cfg.hw_cfg.reserved = 0; @@ -183,46 +185,53 @@ void set_hw_version(void) { else cfg.hw_cfg.shtc3 = 0; // = 0 - sensor SHT4x or ? #if DEVICE_TYPE == DEVICE_LYWSD03MMC +/* The version is determined by the addresses of the display and sensor on I2C + + HW | LCD I2C addr | SHTxxx I2C addr | Note + -- | -- | -- | -- + B1.4 | 0x3C | 0x70 (SHTC3) |   + B1.6 | UART! | 0x44 (SHT4x) |   + B1.7 | 0x3C | 0x44 (SHT4x) | Test original string HW + B1.9 | 0x3E | 0x44 (SHT4x) |   + B2.0 | 0x3C | 0x44 (SHT4x) | Test original string HW + + Version 1.7 or 2.0 is determined at first run by reading the HW line written in Flash. + Display matrices or controllers are different for all versions, except B1.7 = B2.0. */ #if USE_DEVICE_INFO_CHR_UUID #else uint8_t my_HardStr[4]; #endif + uint8_t hwver = 0; if (lcd_i2c_addr == (B14_I2C_ADDR << 1)) { if (cfg.hw_cfg.shtc3) { // sensor SHTC3 ? - cfg.hw_cfg.hwver = HW_VER_LYWSD03MMC_B14; // HW:B1.4 + hwver = HW_VER_LYWSD03MMC_B14; // HW:B1.4 } else { // sensor SHT4x or ? - cfg.hw_cfg.hwver = HW_VER_LYWSD03MMC_B17; // HW:B1.7 + hwver = HW_VER_LYWSD03MMC_B17; // HW:B1.7 or B2.0 + if(flash_read_cfg(&my_HardStr, EEP_ID_HWV, sizeof(my_HardStr)) == sizeof(my_HardStr) + && my_HardStr[0] == 'B' + && my_HardStr[2] == '.') { + if (my_HardStr[1] == '1') + my_HardStr[3] = '7'; + else if(my_HardStr[1] == '2') { + my_HardStr[3] = '0'; + } + flash_write_cfg(&my_HardStr, EEP_ID_HWV, sizeof(my_HardStr)); + return; + } } - } else if (lcd_i2c_addr == (B19_I2C_ADDR << 1)) { - cfg.hw_cfg.hwver = HW_VER_LYWSD03MMC_B19; // HW:B1.9 } else { - cfg.hw_cfg.hwver = HW_VER_LYWSD03MMC_B16; // HW:B1.6 - } - if (flash_read_cfg(&my_HardStr, EEP_ID_HWV, sizeof(my_HardStr)) != sizeof(my_HardStr) - || my_HardStr[0] != 'B' - || my_HardStr[2] != '.' ) { - my_HardStr[0] = 'B'; - my_HardStr[1] = '1'; - my_HardStr[2] = '.'; - /* 0 - LYWSD03MMC B1.4 - 3 - LYWSD03MMC B1.9 - 4 - LYWSD03MMC B1.6 - 5 - LYWSD03MMC B1.7 */ - switch(cfg.hw_cfg.hwver) { - case 3: // HW:B1.9 - my_HardStr[3] = '9'; - break; - case 4: // HW:B1.6 - my_HardStr[3] = '6'; - break; - case 5: // HW:B1.7 - my_HardStr[3] = '7'; - break; - default: // HW:B1.4 - my_HardStr[3] = '4'; - } - flash_write_cfg(&my_HardStr, EEP_ID_HWV, sizeof(my_HardStr)); + if (lcd_i2c_addr == (B19_I2C_ADDR << 1)) + hwver = HW_VER_LYWSD03MMC_B19; // HW:B1.9 + else + hwver = HW_VER_LYWSD03MMC_B16; // HW:B1.6 } + my_HardStr[0] = 'B'; + my_HardStr[1] = '1'; + my_HardStr[2] = '.'; + my_HardStr[3] = id2hwver[hwver & 7]; + cfg.hw_cfg.hwver = hwver; + flash_write_cfg(&my_HardStr, EEP_ID_HWV, sizeof(my_HardStr)); + return; #elif DEVICE_TYPE == DEVICE_MHO_C401 cfg.hw_cfg.hwver = HW_VER_MHO_C401; #elif DEVICE_TYPE == DEVICE_CGG1 @@ -271,7 +280,7 @@ void test_config(void) { measurement_step_time = adv_interval * cfg.measure_interval * (625 * sys_tick_per_us) - 250; // measurement_step_time = adv_interval * 62.5 * measure_interval, max 250 sec - if(cfg.connect_latency > DEF_CONNECT_LATENCY && measured_data.battery_mv < 2800) + if(cfg.connect_latency > DEF_CONNECT_LATENCY && measured_data.average_battery_mv < LOW_VBAT_MV) cfg.connect_latency = DEF_CONNECT_LATENCY; /* interval = 16; * connection_interval_ms = (interval * 125) / 100; @@ -295,9 +304,13 @@ void test_config(void) { } my_periConnParameters.timeout = connection_timeout; #if DEVICE_TYPE != DEVICE_MJWSD05MMC +#if USE_EPD + if (cfg.min_step_time_update_lcd < USE_EPD) // min 0.5 sec: (10*50ms) + cfg.min_step_time_update_lcd = USE_EPD; +#endif if (cfg.min_step_time_update_lcd < 10) // min 0.5 sec: (10*50ms) cfg.min_step_time_update_lcd = 10; - min_step_time_update_lcd = cfg.min_step_time_update_lcd * (50 * CLOCK_16M_SYS_TIMER_CLK_1MS); + lcd_flg.min_step_time_update_lcd = cfg.min_step_time_update_lcd * (50 * CLOCK_16M_SYS_TIMER_CLK_1MS); #endif my_RxTx_Data[0] = CMD_ID_CFG; my_RxTx_Data[1] = VERSION; @@ -309,14 +322,14 @@ void low_vbat(void) { #if DEVICE_TYPE == DEVICE_MJWSD05MMC show_low_bat(); #else -#if ((DEVICE_TYPE == DEVICE_MHO_C401) || (DEVICE_TYPE == DEVICE_MHO_C401N) || (DEVICE_TYPE == DEVICE_CGG1)) +#if (USE_EPD) while(task_lcd()) pm_wait_ms(10); #endif show_temp_symbol(0); #if (DEVICE_TYPE != DEVICE_CGDK2) show_smiley(0); #endif - show_big_number_x10(measured_data.battery_mv * 10); + show_big_number_x10(measured_data.average_battery_mv * 10); #if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) show_small_number_x10(-1023, 1); // "Lo" #else @@ -324,7 +337,7 @@ void low_vbat(void) { #endif show_battery_symbol(1); update_lcd(); -#if ((DEVICE_TYPE == DEVICE_MHO_C401) || (DEVICE_TYPE == DEVICE_MHO_C401N) || (DEVICE_TYPE == DEVICE_CGG1)) +#if (USE_EPD) while(task_lcd()) pm_wait_ms(10); #endif #endif @@ -376,16 +389,16 @@ void WakeupLowPowerCb(int par) { rds_input_off(); } #endif - end_measure = 1; + end_measure = 0xff; + wrk_measure = 0; #if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; + SET_LCD_UPDATE(); #endif - wrk_measure = 0; - } + } timer_measure_cb = 0; bls_pm_setAppWakeupLowPower(0, 0); // clear callback - if (measured_data.battery_mv < 2000) // It is not recommended to write Flash below 2V + if (measured_data.battery_mv < END_VBAT_MV) // It is not recommended to write Flash below 2V low_vbat(); } @@ -418,13 +431,45 @@ static void suspend_enter_cb(u8 e, u8 *p, int n) { #endif //--- check battery -_attribute_ram_code_ void check_battery(void) { +#define BAT_AVERAGE_SHL 4 // 2..7 +#define BAT_AVERAGE_COUNT (1 << BAT_AVERAGE_SHL) // 8,16,32, ... +RAM struct { + uint16_t buf[BAT_AVERAGE_COUNT]; + uint8_t index; +} bat_average; + +_attribute_ram_code_ +void check_battery(void) { + uint32_t i, summ = 0; measured_data.battery_mv = get_battery_mv(); - measured_data.battery_level = get_battery_level(measured_data.battery_mv); + bat_average.index++; + bat_average.index &= (BAT_AVERAGE_COUNT - 1); + bat_average.buf[bat_average.index] = measured_data.battery_mv; + for(i = 0; i < BAT_AVERAGE_COUNT; i++) + summ += bat_average.buf[i]; + measured_data.average_battery_mv = summ >> BAT_AVERAGE_SHL; + measured_data.battery_level = get_battery_level(measured_data.average_battery_mv); } -#if (DEVICE_TYPE == DEVICE_LYWSD03MMC) || (DEVICE_TYPE == DEVICE_MJWSD05MMC) -#if DEVICE_TYPE == DEVICE_MJWSD05MMC +static void start_tst_battery(void) { + int i; + measured_data.battery_mv = get_battery_mv(); + if (measured_data.battery_mv < MIN_VBAT_MV) { // 2.2V +#if (DEVICE_TYPE == DEVICE_LYWSD03MMC) + // Set LYWSD03MMC sleep < 1 uA + init_i2c(); + send_i2c_word(0x70 << 1, 0x98b0); // SHTC3 go SLEEP: Sleep command of the sensor + send_i2c_byte(0x3E << 1, 0xEA); // BU9792AFUV reset +#endif + cpu_sleep_wakeup(DEEPSLEEP_MODE, PM_WAKEUP_TIMER, + clock_time() + 120 * CLOCK_16M_SYS_TIMER_CLK_1S); // go deep-sleep 2 minutes + } + measured_data.average_battery_mv = measured_data.battery_mv; + for(i = 0; i < BAT_AVERAGE_COUNT; i++) + bat_average.buf[i] = measured_data.battery_mv; +} + +#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) extern unsigned char *_icload_size_div_16_; extern unsigned char *_bin_size_; @@ -479,7 +524,9 @@ void test_first_ota(void) { } } } -#endif +#endif // DEVICE_TYPE == DEVICE_MJWSD05MMC + +#if (DEVICE_TYPE == DEVICE_LYWSD03MMC) || (DEVICE_TYPE == DEVICE_MJWSD05MMC) /* * Read HW version * Flash LYWSD03MMC: @@ -505,7 +552,7 @@ uint32_t get_mi_hw_version(void) { } return hw; } -#endif // DEVICE_TYPE == DEVICE_LYWSD03MMC / DEVICE_TYPE == DEVICE_MJWSD05MMC +#endif // DEVICE_TYPE == DEVICE_LYWSD03MMC or DEVICE_TYPE == DEVICE_MJWSD05MMC #if USE_SECURITY_BEACON void bindkey_init(void) { @@ -537,19 +584,31 @@ void bindkey_init(void) { } #endif // USE_SECURITY_BEACON -//------------------ user_init_normal ------------------- +#ifdef GPIO_KEY2 +void set_default_cfg(void) { + memcpy(&cfg, &def_cfg, sizeof(cfg)); + if(!cfg.hw_cfg.shtc3) + cfg.flg.lp_measures = 1; + flash_write_cfg(&cfg, EEP_ID_CFG, sizeof(cfg)); +#if (defined(SHOW_REBOOT_SCREEN) && SHOW_REBOOT_SCREEN) + show_reboot_screen(); +#endif + cpu_sleep_wakeup(DEEPSLEEP_MODE, PM_WAKEUP_TIMER, + clock_time() + 2*CLOCK_16M_SYS_TIMER_CLK_1S); // go deep-sleep 2 sec + while(1) + start_reboot(); +} +#endif // GPIO_KEY2 + +//========================================================= +//-------------------- user_init_normal ------------------- void user_init_normal(void) {//this will get executed one time after power up bool next_start = false; unsigned int old_ver; adc_power_on_sar_adc(0); // - 0.4 mA lpc_power_down(); blc_ll_initBasicMCU(); //must - if (get_battery_mv() < MIN_VBAT_MV) { // 2.2V - init_sensor(); - sensor_go_sleep(); // SHTC3 go SLEEP - cpu_sleep_wakeup(DEEPSLEEP_MODE, PM_WAKEUP_TIMER, - clock_time() + 120 * CLOCK_16M_SYS_TIMER_CLK_1S); // go deep-sleep 2 minutes - } + start_tst_battery(); random_generator_init(); //must #if (DEVICE_TYPE == DEVICE_MJWSD05MMC) test_first_ota(); // Correct FW OTA address? Reformat Big OTA to Low OTA @@ -664,6 +723,7 @@ void user_init_normal(void) {//this will get executed one time after power up start_measure = 1; } +//========================================================= //------------------ user_init_deepRetn ------------------- _attribute_ram_code_ void user_init_deepRetn(void) {//after sleep this will get executed @@ -673,164 +733,8 @@ void user_init_deepRetn(void) {//after sleep this will get executed bls_ota_registerStartCmdCb(app_enter_ota_mode); } -#if(DEVICE_TYPE != DEVICE_MJWSD05MMC) - -_attribute_ram_code_ uint8_t is_comfort(int16_t t, uint16_t h) { - uint8_t ret = SMILE_SAD; - if (t >= cmf.t[0] && t <= cmf.t[1] && h >= cmf.h[0] && h <= cmf.h[1]) - ret = SMILE_HAPPY; - return ret; -} - -_attribute_ram_code_ __attribute__((optimize("-Os"))) void lcd(void) { - bool set_small_number_and_bat = true; - show_stage++; - if (chow_tick_sec >= utc_time_sec && (show_stage & 2)) { // show ext data - if (show_stage & 1) { // stage blinking or show battery or clock - if (cfg.flg.show_batt_enabled -#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) -#else - || measured_data.battery_level <= 15 -#endif - ) { // Battery -#if (DEVICE_TYPE != DEVICE_CGDK2) - show_smiley(0); // stage show battery -#endif - show_battery_symbol(1); -#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) -#if DEVICE_TYPE == DEVICE_CGG1 - show_batt_cgg1(); -#else - show_batt_cgdk2(); -#endif -#else - show_small_number((measured_data.battery_level >= 100) ? 99 : measured_data.battery_level, 1); -#endif // (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) - set_small_number_and_bat = false; - } else if (cfg.flg.blinking_time_smile) { // blinking on -#if USE_CLOCK - show_clock(); // stage clock - show_ble_symbol(ble_connected); - return; -#else -#if (DEVICE_TYPE != DEVICE_CGDK2) - show_smiley(0); // stage blinking and blinking on -#endif -#endif - } -#if (DEVICE_TYPE != DEVICE_CGDK2) - else - show_smiley(*((uint8_t *) &ext.flg)); -#endif - } -#if (DEVICE_TYPE != DEVICE_CGDK2) - else - show_smiley(*((uint8_t *) &ext.flg)); -#endif - if (set_small_number_and_bat) { - show_battery_symbol(ext.flg.battery); -#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) - show_small_number_x10(ext.small_number, ext.flg.percent_on); -#else - show_small_number(ext.small_number, ext.flg.percent_on); -#endif - } - show_temp_symbol(*((uint8_t *) &ext.flg)); - show_big_number_x10(ext.big_number); - } else { - if (show_stage & 1) { // stage blinking or show battery -#if USE_CLOCK - if (cfg.flg.blinking_time_smile && (show_stage & 2)) { - show_clock(); // stage clock - show_ble_symbol(ble_connected); - return; - } -#endif - if (cfg.flg.show_batt_enabled -#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) -#else - || measured_data.battery_level <= 15 -#endif - ) { // Battery -#if (DEVICE_TYPE != DEVICE_CGDK2) - show_smiley(0); // stage show battery -#endif - show_battery_symbol(1); -#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) -#if DEVICE_TYPE == DEVICE_CGG1 - show_batt_cgg1(); -#else - show_batt_cgdk2(); -#endif -#else - show_small_number((measured_data.battery_level >= 100) ? 99 : measured_data.battery_level, 1); -#endif // (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) - set_small_number_and_bat = false; - } else if (cfg.flg.blinking_time_smile) { // blinking on -#if USE_CLOCK - show_clock(); // stage clock - show_ble_symbol(ble_connected); - return; -#else -#if (DEVICE_TYPE != DEVICE_CGDK2) - show_smiley(0); // stage blinking and blinking on -#endif -#endif - } else { -#if (DEVICE_TYPE != DEVICE_CGDK2) - if (cfg.flg.comfort_smiley) { // no blinking on + comfort - show_smiley(is_comfort(measured_data.temp, measured_data.humi)); - } else - show_smiley(cfg.flg2.smiley); // no blinking -#endif - } - } else { -#if (DEVICE_TYPE != DEVICE_CGDK2) - if (cfg.flg.comfort_smiley) { // no blinking on + comfort - show_smiley(is_comfort(measured_data.temp, measured_data.humi)); - } else - show_smiley(cfg.flg2.smiley); // no blinking -#endif - } - if (set_small_number_and_bat) { -#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) - show_battery_symbol(!cfg.flg.show_batt_enabled); - show_small_number_x10(measured_data.humi_x01, 1); -#else - show_battery_symbol(0); - show_small_number(measured_data.humi_x1, 1); -#endif - } - if (cfg.flg.temp_F_or_C) { - show_temp_symbol(TMP_SYM_F); // "°F" - show_big_number_x10((((measured_data.temp / 5) * 9) + 3200) / 10); // convert C to F - } else { - show_temp_symbol(TMP_SYM_C); // "°C" - show_big_number_x10(measured_data.temp_x01); - } - } - show_ble_symbol(ble_connected); -} -#endif // (DEVICE_TYPE != DEVICE_MJWSD05MMC) - -#ifdef GPIO_KEY2 -void set_default_cfg(void) { - memcpy(&cfg, &def_cfg, sizeof(cfg)); - if(!cfg.hw_cfg.shtc3) - cfg.flg.lp_measures = 1; - flash_write_cfg(&cfg, EEP_ID_CFG, sizeof(cfg)); -#if (defined(SHOW_REBOOT_SCREEN) && SHOW_REBOOT_SCREEN) - show_reboot_screen(); -#endif - cpu_sleep_wakeup(DEEPSLEEP_MODE, PM_WAKEUP_TIMER, - clock_time() + 2*CLOCK_16M_SYS_TIMER_CLK_1S); // go deep-sleep 2 sec - while(1) - start_reboot(); -} -#endif // GPIO_KEY2 - -//============================================= -//----------------------- main_loop() +//========================================================= +//----------------------- main_loop() --------------------- _attribute_ram_code_ void main_loop(void) { blt_sdk_main_loop(); @@ -844,9 +748,7 @@ void main_loop(void) { rtc.minutes = 0; rtc_sync_utime = utc_time_sec; } -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; -#endif + SET_LCD_UPDATE(); } #endif } @@ -912,19 +814,12 @@ void main_loop(void) { bls_pm_setAppWakeupLowPower(0, 0); // clear callback if ((blc_ll_getCurrentState() & BLS_LINK_STATE_CONN) && blc_ll_getTxFifoNumber() < 9) { // connect, TxFifo ready - if (end_measure) { - end_measure = 0; - if (RxTxValueInCCC) { - if (tx_measures) { - if (tx_measures != 0xff) - tx_measures--; - ble_send_measures(); - } - if (lcd_flg.b.new_update) { - // LCD for send notify - lcd_flg.b.new_update = 0; - ble_send_lcd(); - } + if (end_measure & 1) { + end_measure &= ~1; + if (RxTxValueInCCC && tx_measures) { + if (tx_measures != 0xff) + tx_measures--; + ble_send_measures(); } if (batteryValueInCCC) ble_send_battery(); @@ -940,6 +835,12 @@ void main_loop(void) { } else if (rd_memo.cnt) { send_memo_blk(); #endif + } else if (RxTxValueInCCC) { + if (lcd_flg.b.send_notify) { + // LCD for send notify + lcd_flg.b.send_notify = 0; + ble_send_lcd(); + } } } #if USE_RTC @@ -956,18 +857,14 @@ void main_loop(void) { key_pressed_tik = new; key_pressed_tiks = new; set_adv_con_time(0); -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; -#endif + SET_LCD_UPDATE(); } else { if(new - key_pressed_tik > 1750*CLOCK_16M_SYS_TIMER_CLK_1MS) { key_pressed_tik = new; if(++cfg.flg2.screen_type > SCR_TYPE_EXT) cfg.flg2.screen_type = SCR_TYPE_TIME; -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; -#endif + SET_LCD_UPDATE(); } if(new - key_pressed_tiks > 5*CLOCK_16M_SYS_TIMER_CLK_1S) { if((reg_gpio_in(GPIO_KEY1) & (GPIO_KEY1 & 0xff))==0) @@ -982,9 +879,7 @@ void main_loop(void) { key_pressed_tiks = new; if(rest_adv_int_tad < -80) { set_adv_con_time(1); -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; -#endif + SET_LCD_UPDATE(); } } #endif // GPIO_KEY2 @@ -992,27 +887,37 @@ void main_loop(void) { tim_measure = new; start_measure = 1; } -#if ((DEVICE_TYPE == DEVICE_MHO_C401) || (DEVICE_TYPE == DEVICE_MHO_C401N) || (DEVICE_TYPE == DEVICE_CGG1)) - else if ((!stage_lcd) && (new - tim_last_chow >= min_step_time_update_lcd)) { -#elif (DEVICE_TYPE == DEVICE_MJWSD05MMC) - if (lcd_update) { - lcd_update = 0; -#else - if (new - tim_last_chow >= min_step_time_update_lcd) { +#if (USE_EPD) + if ((!stage_lcd) && (new - lcd_flg.tim_last_chow >= lcd_flg.min_step_time_update_lcd)) { + lcd_flg.tim_last_chow = new; + lcd_flg.show_stage++; + if(lcd_flg.update_next_measure) { + lcd_flg.update = end_measure & 2; + end_measure &= ~2; + } else + lcd_flg.update = 1; + } +#elif (DEVICE_TYPE != DEVICE_MJWSD05MMC) + if (new - lcd_flg.tim_last_chow >= lcd_flg.min_step_time_update_lcd) { + lcd_flg.tim_last_chow = new; + lcd_flg.show_stage++; + if(lcd_flg.update_next_measure) { + lcd_flg.update = end_measure & 2; + end_measure &= ~2; + } else + lcd_flg.update = 1; + } #endif - if (!lcd_flg.b.ext_data) { // Not LCD show external data - // set flag LCD for send notify - lcd_flg.b.new_update = lcd_flg.b.notify_on; + if (lcd_flg.update) { + lcd_flg.update = 0; + if (!lcd_flg.b.ext_data_buf) { // LCD show external data ? No lcd(); } update_lcd(); -#if (DEVICE_TYPE != DEVICE_MJWSD05MMC) - tim_last_chow = new; -#endif } } } -#if ((DEVICE_TYPE == DEVICE_MHO_C401) || (DEVICE_TYPE == DEVICE_MHO_C401N) || (DEVICE_TYPE == DEVICE_CGG1)) +#if (USE_EPD) if (wrk_measure == 0 && stage_lcd) { if (task_lcd()) { if(!gpio_read(EPD_BUSY)) { @@ -1022,6 +927,7 @@ void main_loop(void) { bls_pm_setWakeupSource(PM_WAKEUP_PAD); // gpio pad wakeup suspend/deepsleep } } else { + cpu_set_gpio_wakeup(EPD_BUSY, Level_High, 0); // pad high wakeup deepsleep disable bls_pm_setSuspendMask(SUSPEND_DISABLE); return; } diff --git a/src/app.h b/src/app.h index d9d2a652..2c296b4c 100644 --- a/src/app.h +++ b/src/app.h @@ -22,17 +22,6 @@ enum { HW_VER_UNKNOWN = 15 } HW_VERSION_ID; -// EEPROM IDs -#define EEP_ID_CFG (0x0CFC) // EEP ID config data -#define EEP_ID_TRG (0x0DFE) // EEP ID trigger data -#define EEP_ID_RPC (0x0DF5) // EEP ID reed switch pulse counter -#define EEP_ID_PCD (0xC0DE) // EEP ID pincode -#define EEP_ID_CMF (0x0FCC) // EEP ID comfort data -#define EEP_ID_DVN (0x0DB5) // EEP ID device name -#define EEP_ID_TIM (0x0ADA) // EEP ID time adjust -#define EEP_ID_KEY (0xBEAC) // EEP ID bkey -#define EEP_ID_HWV (0x1234) // EEP ID Mi HW version - // Adv. types enum { ADV_TYPE_ATC = 0, @@ -55,7 +44,7 @@ typedef struct __attribute__((packed)) _cfg_t { #if (DEVICE_TYPE == DEVICE_MJWSD05MMC) uint8_t x100 : 1; #else - uint8_t blinking_time_smile : 1; //(USE_CLOCK = 0 - smile, =1 time) + uint8_t show_time_smile : 1; // if USE_CLOCK: = 0 - smile, =1 time, else: blinking on/off #endif uint8_t temp_F_or_C : 1; #if (DEVICE_TYPE == DEVICE_MJWSD05MMC) @@ -193,8 +182,6 @@ typedef struct __attribute__((packed)) _external_data_t { #endif } external_data_t, * pexternal_data_t; extern external_data_t ext; -extern uint32_t chow_tick_clk; // count chow validity time, in clock -extern uint32_t chow_tick_sec; // count chow validity time, in sec extern uint32_t utc_time_sec; // clock in sec (= 0 1970-01-01 00:00:00) #if USE_TIME_ADJUST @@ -207,80 +194,53 @@ extern uint32_t pincode; // pincode (if = 0 - not used) #endif typedef struct _measured_data_t { - uint16_t battery_mv; // mV + uint16_t average_battery_mv; // mV int16_t temp; // x 0.01 C int16_t humi; // x 0.01 % uint16_t count; + uint16_t battery_mv; // mV + int16_t temp_x01; // x 0.1 C int16_t humi_x01; // x 0.1 % uint8_t humi_x1; // x 1 % - uint8_t battery_level; // 0..100% + uint8_t battery_level; // 0..100% (average_battery_mv) } measured_data_t; #define MEASURED_MSG_SIZE 8 extern measured_data_t measured_data; -//extern uint8_t battery_level; // 0..100% -//extern int16_t last_temp; // x0.1 C -//extern uint16_t last_humi; // x1 % - -extern volatile uint8_t tx_measures; // connect notify send measure flag -extern volatile uint8_t start_measure; // start measure all -extern volatile uint8_t wrk_measure; -extern volatile uint8_t end_measure; -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) -extern volatile uint8_t lcd_update; -#endif - -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) -#define MI_HW_VER_FADDR 0x7D000 // Mi HW version -#else -#define MI_HW_VER_FADDR 0x55000 // Mi HW version -#endif - - -extern uint32_t tim_measure; // timer measurements >= 10 sec +extern volatile uint8_t tx_measures; // measurement transfer counter, flag +extern volatile uint8_t start_measure; // start measurements +extern volatile uint8_t wrk_measure; // measurements in process +extern uint8_t end_measure; // measurements completed -typedef union _lcd_flg_t { - struct { - uint8_t ext_data: 1; // LCD show external data - uint8_t notify_on: 1; // Send LCD dump if Notify on - uint8_t res: 5; - uint8_t new_update: 1; // flag update LCD for send notify - }b; - uint8_t uc; -} lcd_flg_t; -extern lcd_flg_t lcd_flg; +extern uint32_t tim_measure; // measurement timer typedef struct _comfort_t { int16_t t[2]; uint16_t h[2]; }scomfort_t, * pcomfort_t; +extern scomfort_t cmf; #if USE_SECURITY_BEACON extern uint8_t bindkey[16]; void bindkey_init(void); #endif -extern scomfort_t cmf; #if BLE_SECURITY_ENABLE extern uint32_t pincode; #endif -extern uint32_t adv_interval; -extern uint32_t connection_timeout; -extern uint32_t measurement_step_time; -extern uint32_t tim_last_chow; // timer show lcd >= 1.5 sec -#if DEVICE_TYPE != DEVICE_MJWSD05MMC -extern uint32_t min_step_time_update_lcd; // = cfg.min_step_time_update_lcd * (50 * CLOCK_16M_SYS_TIMER_CLK_1MS) -#endif +extern uint32_t adv_interval; // adv interval in 0.625 ms // = cfg.advertising_interval * 100 +extern uint32_t connection_timeout; // connection timeout in 10 ms, Tdefault = connection_latency_ms * 4 = 2000 * 4 = 8000 ms +extern uint32_t measurement_step_time; // = adv_interval * measure_interval -void ev_adv_timeout(u8 e, u8 *p, int n); -void test_config(void); +void ev_adv_timeout(u8 e, u8 *p, int n); // DURATION_TIMEOUT Event Callback +void test_config(void); // Test config values void set_hw_version(void); -void reset_cache(void); +//---- blt_common.c void blc_newMacAddress(int flash_addr, u8 *mac_pub, u8 *mac_rand); void SwapMacAddress(u8 *mac_out, u8 *mac_in); void flash_erase_mac_sector(u32 faddr); diff --git a/src/app_config.h b/src/app_config.h index 79d00a2c..010baba7 100644 --- a/src/app_config.h +++ b/src/app_config.h @@ -50,7 +50,6 @@ extern "C" { #define UART_PRINT_DEBUG_ENABLE 0 // =1 use u_printf() (PA7/SWS), source: SDK/components/application/print/u_printf.c #if DEVICE_TYPE == DEVICE_MHO_C401 - // TLSR8251F512ET24 // GPIO_PA5 - used EPD_SHD // GPIO_PA6 - used EPD_RST @@ -63,6 +62,8 @@ extern "C" { // GPIO_PD2 - used EPD_CSB // GPIO_PD7 - used EPD_SCL +#define USE_EPD (600/50 - 1) // min update time x50 ms + #define SHL_ADC_VBAT 1 // "B0P" in adc.h #define GPIO_VBAT GPIO_PB0 // missing pin on case TLSR8251F512ET24 #define PB0_INPUT_ENABLE 1 @@ -157,6 +158,8 @@ extern "C" { // GPIO_PD2 - used EPD_SDA // GPIO_PD7 - used EPD_RST +#define USE_EPD (600/50 - 1) // min update time ms + #define SHL_ADC_VBAT 1 // "B0P" in adc.h #define GPIO_VBAT GPIO_PB0 // missing pin on case TLSR8251F512ET24 #define PB0_INPUT_ENABLE 1 @@ -258,6 +261,8 @@ extern "C" { // GPIO_PD4 - used EPD_BUSY // GPIO_PD7 - used EPD_SCL +#define USE_EPD (550/50 - 1) // min update time ms + #define SHL_ADC_VBAT 1 // "B0P" in adc.h #define GPIO_VBAT GPIO_PB0 // missing pin on case TLSR8253F512ET32 #define PB0_INPUT_ENABLE 1 @@ -376,6 +381,8 @@ extern "C" { // GPIO_PD2 - CS/PWM, free // GPIO_PD7 - free [B1.4], UART TX LCD [B1.6], pcb mark "P7" +#define USE_EPD 0 // min update time ms + #define SHL_ADC_VBAT 1 // "B0P" in adc.h #define GPIO_VBAT GPIO_PB0 // missing pin on case TLSR8251F512ET24 #define PB0_INPUT_ENABLE 1 @@ -428,6 +435,8 @@ extern "C" { #define PC4_FUNC AS_GPIO #endif +#define MI_HW_VER_FADDR 0x55000 // Mi HW version (DEVICE_LYWSD03MMC) + #elif DEVICE_TYPE == DEVICE_CGDK2 // TLSR8253F512ET32 @@ -449,6 +458,8 @@ extern "C" { // GPIO_PD4 - free // GPIO_PD7 - free +#define USE_EPD 0 // min update time ms + #define SHL_ADC_VBAT 1 // "B0P" in adc.h #define GPIO_VBAT GPIO_PB0 // missing pin on case TLSR8253F512ET32 #define PB0_INPUT_ENABLE 1 @@ -548,6 +559,8 @@ extern "C" { // scan i2c: 0x7c, 0x88, 0xa2 +#define USE_EPD 0 // min update time ms + #define SHL_ADC_VBAT 6 // "B5P" in adc.h #define GPIO_VBAT GPIO_PB5 // R5 -> +Vbat //#define PULL_WAKEUP_SRC_PB5 PM_PIN_PULLUP_1M @@ -601,6 +614,8 @@ extern "C" { #define PB6_FUNC AS_GPIO #define PULL_WAKEUP_SRC_PB6 PM_PIN_PULLUP_10K +#define MI_HW_VER_FADDR 0x7D000 // Mi HW version (DEVICE_MJWSD05MMC) + #else // DEVICE_TYPE #error ("DEVICE_TYPE = ?") #endif // DEVICE_TYPE == ? diff --git a/src/battery.h b/src/battery.h index 4a2242f2..fafeec31 100644 --- a/src/battery.h +++ b/src/battery.h @@ -5,6 +5,9 @@ #define MAX_VBAT_MV 2950 // 3100 mV - > battery = 100% no load, 2950 at load (during measurement) #define MIN_VBAT_MV 2200 // 2200 mV - > battery = 0% +#define LOW_VBAT_MV 2800 // level set LOW_CONNECT_LATENCY +#define END_VBAT_MV 2000 // It is not recommended to write Flash below 2V, go to deep-sleep + uint16_t get_adc_mv(uint32_t p_ain); #define get_battery_mv() get_adc_mv(SHL_ADC_VBAT) // Channel B0P/B5P diff --git a/src/ble.c b/src/ble.c index a9a474c8..411ad0e7 100644 --- a/src/ble.c +++ b/src/ble.c @@ -9,6 +9,7 @@ #include "lcd.h" #include "app.h" #include "flash_eep.h" +#include "battery.h" #if USE_TRIGGER_OUT #include "trigger.h" #include "rds_count.h" @@ -94,7 +95,7 @@ void ble_disconnect_callback(uint8_t e, uint8_t *p, int n) { ble_connected = 0; ota_is_working = 0; mi_key_stage = 0; - lcd_flg.uc = 0; + lcd_flg.all_flg = 0; #if USE_FLASH_MEMO rd_memo.cnt = 0; #endif @@ -118,21 +119,13 @@ void ble_disconnect_callback(uint8_t e, uint8_t *p, int n) { } #endif // DEVICE_TYPE == DEVICE_MJWSD05MMC #endif // BLE_EXT_ADV -#ifdef LCD_CONN_SYMBOL - show_connected_symbol(false); -#else -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; -#else // DEVICE_TYPE != DEVICE_MJWSD05MMC - tim_last_chow = clock_time() - min_step_time_update_lcd - (8*CLOCK_16M_SYS_TIMER_CLK_1MS); -#endif -#endif // LCD_CONN_SYMBOL + SHOW_CONNECTED_SYMBOL(false); } void ble_connect_callback(uint8_t e, uint8_t *p, int n) { (void) e; (void) p; (void) n; ble_connected = 1; - if(cfg.connect_latency > DEF_CONNECT_LATENCY && measured_data.battery_mv < 2800) + if(cfg.connect_latency > DEF_CONNECT_LATENCY && measured_data.average_battery_mv < LOW_VBAT_MV) cfg.connect_latency = DEF_CONNECT_LATENCY; my_periConnParameters.latency = cfg.connect_latency; if (cfg.connect_latency) { @@ -141,15 +134,7 @@ void ble_connect_callback(uint8_t e, uint8_t *p, int n) { } my_periConnParameters.timeout = connection_timeout; bls_l2cap_requestConnParamUpdate(my_periConnParameters.intervalMin, my_periConnParameters.intervalMax, my_periConnParameters.latency, my_periConnParameters.timeout); -#ifdef LCD_CONN_SYMBOL - show_connected_symbol(true); -#else -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; -#else - tim_last_chow = clock_time() - min_step_time_update_lcd - (8*CLOCK_16M_SYS_TIMER_CLK_1MS); -#endif -#endif + SHOW_CONNECTED_SYMBOL(true); #ifdef GPIO_KEY2 rest_adv_int_tad = 0; #endif @@ -203,7 +188,7 @@ int app_advertise_prepare_handler(rf_packet_adv_t * p) { #endif { if (adv_buf.old_measured_count != measured_data.count) { // new measured_data ? - adv_buf.old_measured_count = measured_data.count; // save + adv_buf.old_measured_count = measured_data.count; // save measured count adv_buf.call_count = 1; // count 1..cfg.measure_interval adv_buf.send_count++; // count & id advertise, = beacon_nonce.cnt32 adv_buf.update_count = 0; @@ -218,11 +203,11 @@ int app_advertise_prepare_handler(rf_packet_adv_t * p) { } #ifdef GPIO_KEY2 if(rest_adv_int_tad) { + rest_adv_int_tad--; #if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - if ((rest_adv_int_tad & 1) == 0) - lcd_update = 1; + if (rest_adv_int_tad & 1) + SET_LCD_UPDATE(); // show "ble" #endif - rest_adv_int_tad--; } #endif } @@ -230,7 +215,6 @@ int app_advertise_prepare_handler(rf_packet_adv_t * p) { else { // restore next adv. interval blta.adv_interval = EXT_ADV_INTERVAL*625*CLOCK_16M_SYS_TIMER_CLK_1US; // system tick - // set_rds_adv_data(); } #endif return 1; // = 1 ready to send ADV packet, = 0 not send ADV @@ -369,8 +353,9 @@ int app_host_event_callback(u32 h, u8 *para, int n) { #endif extern attribute_t my_Attributes[ATT_END_H]; -const char* hex_ascii = { "0123456789ABCDEF" }; -void ble_get_name(void) { +static const char* hex_ascii = { "0123456789ABCDEF" }; + +void ble_set_name(void) { int16_t len = flash_read_cfg(&ble_name[2], EEP_ID_DVN, min(sizeof(ble_name)-3, 31-2)); if (len < 1) { //Set the BLE Name to the last three MACs the first ones are always the same @@ -431,7 +416,7 @@ __attribute__((optimize("-Os"))) void init_ble(void) { ////////////////// BLE stack initialization ////////////////////// blc_initMacAddress(CFG_ADR_MAC, mac_public, mac_random_static); /// if bls_ll_setAdvParam( OWN_ADDRESS_RANDOM ) -> blc_ll_setRandomAddr(mac_random_static); - ble_get_name(); + ble_set_name(); ////// Controller Initialization ////////// //blc_ll_initBasicMCU(); // -> app.c user_init_normal() blc_ll_initStandby_module(mac_public); //must @@ -439,37 +424,35 @@ __attribute__((optimize("-Os"))) void init_ble(void) { blc_ll_initConnection_module(); // connection module must for BLE slave/master blc_ll_initSlaveRole_module(); // slave module: must for BLE slave, blc_ll_initPowerManagement_module(); //pm module: optional +#if (BLE_EXT_ADV) + ext_adv_init = 0; +#endif if (cfg.flg2.bt5phy) { // 1M, 2M, Coded PHY blc_ll_init2MPhyCodedPhy_feature(); //if use 2M or Coded PHY // set Default Connection Coding blc_ll_setDefaultConnCodingIndication(CODED_PHY_PREFER_S8); // set Default Connection Coding -#if (BLE_EXT_ADV) - if(cfg.flg2.longrange) - blc_ll_setDefaultPhy(PHY_TRX_PREFER, BLE_PHY_CODED, BLE_PHY_CODED); - else -#endif - blc_ll_setDefaultPhy(PHY_TRX_PREFER, PHY_PREFER_1M, PHY_PREFER_1M); // set CSA2 blc_ll_initChannelSelectionAlgorithm_2_feature(); //bls_app_registerEventCallback (BLT_EV_FLAG_PHY_UPDATE, &callback_phy_update_complete_event); - } #if (BLE_EXT_ADV) - if (cfg.flg2.longrange) { // support extension advertise Coded PHY - // init buffers ext adv - // and ll_module_adv_cb = blt_ext_adv_proc; pFunc_ll_SetAdv_Enable = ll_setExtAdv_Enable; - blc_ll_initExtendedAdvertising_module(app_adv_set_param, app_primary_adv_pkt, APP_ADV_SETS_NUMBER); - blc_ll_initExtSecondaryAdvPacketBuffer(app_secondary_adv_pkt, MAX_LENGTH_SECOND_ADV_PKT); - blc_ll_initExtAdvDataBuffer(app_advData, APP_MAX_LENGTH_ADV_DATA); - blc_ll_initExtScanRspDataBuffer(app_scanRspData, APP_MAX_LENGTH_SCAN_RESPONSE_DATA); - // if Coded PHY is used, this API set default S2/S8 mode for Extended ADV - blc_ll_setDefaultExtAdvCodingIndication(ADV_HANDLE0, CODED_PHY_PREFER_S8); - // patch, set advertise prepare user cb (app_advertise_prepare_handler) - ll_module_adv_cb = _blt_ext_adv_proc; - ext_adv_init = 1; // flag ext_adv init - } else - ext_adv_init = 0; + if(cfg.flg2.longrange) { // support extension advertise Coded PHY + // init buffers ext adv + // and ll_module_adv_cb = blt_ext_adv_proc; pFunc_ll_SetAdv_Enable = ll_setExtAdv_Enable; + blc_ll_initExtendedAdvertising_module(app_adv_set_param, app_primary_adv_pkt, APP_ADV_SETS_NUMBER); + blc_ll_initExtSecondaryAdvPacketBuffer(app_secondary_adv_pkt, MAX_LENGTH_SECOND_ADV_PKT); + blc_ll_initExtAdvDataBuffer(app_advData, APP_MAX_LENGTH_ADV_DATA); + blc_ll_initExtScanRspDataBuffer(app_scanRspData, APP_MAX_LENGTH_SCAN_RESPONSE_DATA); + // if Coded PHY is used, this API set default S2/S8 mode for Extended ADV + blc_ll_setDefaultExtAdvCodingIndication(ADV_HANDLE0, CODED_PHY_PREFER_S8); + // patch, set advertise prepare user cb (app_advertise_prepare_handler) + ll_module_adv_cb = _blt_ext_adv_proc; + ext_adv_init = 1; // flag ext_adv init + blc_ll_setDefaultPhy(PHY_TRX_PREFER, BLE_PHY_CODED, BLE_PHY_CODED); + } else #endif + blc_ll_setDefaultPhy(PHY_TRX_PREFER, PHY_PREFER_1M, PHY_PREFER_1M); + } ////// Host Initialization ////////// blc_gap_peripheral_init(); my_att_init(); //gatt initialization @@ -550,7 +533,7 @@ __attribute__((optimize("-Os"))) void init_ble(void) { blc_l2cap_registerConnUpdateRspCb(app_conn_param_update_response); bls_set_advertise_prepare(app_advertise_prepare_handler); // TODO: not work if EXTENDED_ADVERTISING #if USE_WK_RDS_COUNTER - bls_app_registerEventCallback (BLT_EV_FLAG_ADV_DURATION_TIMEOUT, &ev_adv_timeout); + bls_app_registerEventCallback(BLT_EV_FLAG_ADV_DURATION_TIMEOUT, &ev_adv_timeout); #endif ev_adv_timeout(0,0,0); } diff --git a/src/ble.h b/src/ble.h index 7eda140c..91584195 100644 --- a/src/ble.h +++ b/src/ble.h @@ -24,7 +24,7 @@ typedef struct _adv_buf_t { uint8_t update_count; // refresh adv_buf.data in next set_adv_data() uint8_t call_count; // count 1..cfg.measure_interval uint8_t data_size; - uint8_t flag[3]; + uint8_t flag[3]; // Advertise type flags uint8_t data[ADV_BUFFER_SIZE]; }adv_buf_t; extern adv_buf_t adv_buf; @@ -189,8 +189,7 @@ void set_adv_data(void); void my_att_init(); void init_ble(); -void ble_get_name(void); -bool ble_get_connected(); +void ble_set_name(void); void ble_send_measures(void); void ble_send_ext(void); void ble_send_lcd(void); diff --git a/src/cmd_parser.c b/src/cmd_parser.c index b050f80f..ef761977 100644 --- a/src/cmd_parser.c +++ b/src/cmd_parser.c @@ -419,9 +419,11 @@ void cmd_parser(void * p) { if (--len > sizeof(ext)) len = sizeof(ext); if (len) { memcpy(&ext, &req->dat[1], len); - chow_tick_sec = utc_time_sec + ext.vtime_sec; + lcd_flg.chow_ext_ut = utc_time_sec + ext.vtime_sec; #if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; + SET_LCD_UPDATE(); +#else + lcd_flg.update_next_measure = 0; #endif } ble_send_ext(); @@ -431,7 +433,9 @@ void cmd_parser(void * p) { if (len) { memcpy(&cfg, &req->dat[1], len); #if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; + SET_LCD_UPDATE(); +#else + lcd_flg.update_next_measure = 0; #endif } test_config(); @@ -450,7 +454,6 @@ void cmd_parser(void * p) { } memcpy(&cfg, &def_cfg, sizeof(cfg)); test_config(); -// set_hw_version(); if (!cfg.hw_cfg.shtc3) // sensor SHT4x ? cfg.flg.lp_measures = 1; ev_adv_timeout(0, 0, 0); @@ -540,16 +543,17 @@ void cmd_parser(void * p) { len = sizeof(display_buff); if (len) { memcpy(display_buff, &req->dat[1], len); - lcd_flg.b.ext_data = 1; // update_lcd(); -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; -#endif - } else lcd_flg.b.ext_data = 0; + lcd_flg.b.ext_data_buf = 1; // update_lcd(); + lcd_flg.update = 1; // SET_LCD_UPDATE(); + } else if(lcd_flg.b.ext_data_buf) { + lcd_flg.b.ext_data_buf = 0; + lcd_flg.update = 1; // SET_LCD_UPDATE(); + } ble_send_lcd(); } else if (cmd == CMD_ID_LCD_FLG) { // Start/stop notify lcd dump and ... if (len > 1) - lcd_flg.uc = req->dat[1]; - send_buf[1] = lcd_flg.uc; + lcd_flg.all_flg = req->dat[1]; + send_buf[1] = lcd_flg.all_flg; olen = 2; #if BLE_SECURITY_ENABLE } else if (cmd == CMD_ID_PINCODE && len > 4) { // Set new pinCode 0..999999 @@ -577,7 +581,7 @@ void cmd_parser(void * p) { if (--len > SEND_BUFFER_SIZE - 1) len = SEND_BUFFER_SIZE - 1; if (len) { flash_write_cfg(&req->dat[1], EEP_ID_DVN, (req->dat[1] != 0)? len : 0); - ble_get_name(); + ble_set_name(); ble_connected |= 0x80; // reset device on disconnect } memcpy(&send_buf[1], &ble_name[2], ble_name[0] - 1); @@ -602,9 +606,7 @@ void cmd_parser(void * p) { #if USE_RTC rtc_set_utime(utc_time_sec); #endif -#if (DEVICE_TYPE == DEVICE_MJWSD05MMC) - lcd_update = 1; -#endif + SET_LCD_UPDATE(); } memcpy(&send_buf[1], &utc_time_sec, sizeof(utc_time_sec)); #if USE_TIME_ADJUST @@ -702,10 +704,29 @@ void cmd_parser(void * p) { } // Debug commands (unsupported in different versions!): + } else if (cmd == CMD_ID_EEP_RW && len > 2) { + send_buf[1] = req->dat[1]; + send_buf[2] = req->dat[2]; + olen = req->dat[1] | (req->dat[2] << 8); + if(len > 3) { + flash_write_cfg(&req->dat[3], olen, len - 3); + } + int16_t i = flash_read_cfg(&send_buf[3], olen, SEND_BUFFER_SIZE - 3); + if(i < 0) { + send_buf[1] = (uint8_t)(i & 0xff); // Error + olen = 2; + } else + olen = i + 3; } else if (cmd == CMD_ID_DEBUG && len > 3) { // test/debug _flash_read((req->dat[1] | (req->dat[2]<<8) | (req->dat[3]<<16)), 18, &send_buf[4]); memcpy(send_buf, req->dat, 4); olen = 18+4; + } else if (cmd == CMD_ID_LR_RESET) { // Reset Long Range + cfg.flg2.longrange = 0; + cfg.flg2.bt5phy = 0; + flash_write_cfg(&cfg, EEP_ID_CFG, sizeof(cfg)); + ble_send_cfg(); + ble_connected |= 0x80; // reset device on disconnect } else { send_buf[1] = 0xff; // Error cmd olen = 2; diff --git a/src/cmd_parser.h b/src/cmd_parser.h index 133ed2e2..6a607d1c 100644 --- a/src/cmd_parser.h +++ b/src/cmd_parser.h @@ -34,7 +34,10 @@ enum { CMD_ID_SET_OTA = 0x73, // Extension BigOTA: Get/set address and size OTA, erase sectors // Debug commands (unsupported in different versions!): + CMD_ID_EEP_RW = 0xDC, // Get/set EEP + CMD_ID_LR_RESET = 0xDD, // Reset Long Range CMD_ID_DEBUG = 0xDE // Test/Debug + } CMD_ID_KEYS; #define MI_KEYTBIND_ID 0x10 // id token + bindkey diff --git a/src/custom_beacon.c b/src/custom_beacon.c index 0799d2c9..04e85d5d 100644 --- a/src/custom_beacon.c +++ b/src/custom_beacon.c @@ -99,7 +99,7 @@ void pvvx_data_beacon(void) { p->UUID = ADV_CUSTOM_UUID16; // GATT Service 0x181A Environmental Sensing (little-endian) p->temperature = measured_data.temp; // x0.01 C p->humidity = measured_data.humi; // x0.01 % - p->battery_mv = measured_data.battery_mv; // x mV + p->battery_mv = measured_data.average_battery_mv; // x mV p->battery_level = measured_data.battery_level; // x1 % p->counter = (uint8_t)adv_buf.send_count; #if USE_TRIGGER_OUT @@ -127,8 +127,8 @@ void atc_data_beacon(void) { p->temperature[1] = (uint8_t)measured_data.temp_x01; // x0.1 C p->humidity = measured_data.humi_x1; // x1 % p->battery_level = measured_data.battery_level; // x1 % - p->battery_mv[0] = (uint8_t)(measured_data.battery_mv >> 8); - p->battery_mv[1] = (uint8_t)measured_data.battery_mv; // x1 mV + p->battery_mv[0] = (uint8_t)(measured_data.average_battery_mv >> 8); + p->battery_mv[1] = (uint8_t)measured_data.average_battery_mv; // x1 mV p->counter = (uint8_t)adv_buf.send_count; } diff --git a/src/epd_cgg1.c b/src/epd_cgg1.c index 84800e7d..840f63f5 100644 --- a/src/epd_cgg1.c +++ b/src/epd_cgg1.c @@ -13,8 +13,6 @@ #define DEF_EPD_SUMBOL_SIGMENTS 13 #define DEF_EPD_REFRESH_CNT 32 -RAM uint8_t display_buff[18]; -RAM uint8_t display_cmp_buff[18]; RAM uint8_t stage_lcd; RAM uint8_t flg_lcd_init; RAM uint8_t lcd_refresh_cnt; @@ -40,8 +38,8 @@ const uint8_t bottom_left[DEF_EPD_SUMBOL_SIGMENTS*2] = {13, 1, 13, 2, 14, 2, 14, const uint8_t bottom_middle[DEF_EPD_SUMBOL_SIGMENTS*2] = {9, 6, 8, 3, 8, 2, 8, 1, 8, 4, 7, 3, 10, 5, 10, 4, 10, 6, 9, 5, 9, 0, 10, 7, 9, 7}; const uint8_t bottom_right[DEF_EPD_SUMBOL_SIGMENTS*2] = {5, 1, 5, 2, 7, 7, 3, 2, 3, 4, 0, 1, 0, 0, 3, 5, 3, 3, 3, 0, 7, 6, 6, 0, 3, 1}; -#define delay_SPI_end_cycle() cpu_stall_wakeup_by_timer0((CLOCK_SYS_CLOCK_1US*15)/10) // real clk 4.4 + 4.4 us : 114 kHz) -#define delay_EPD_SCL_pulse() cpu_stall_wakeup_by_timer0((CLOCK_SYS_CLOCK_1US*15)/10) // real clk 4.4 + 4.4 us : 114 kHz) +#define delay_SPI_end_cycle() sleep_us(2) +#define delay_EPD_SCL_pulse() sleep_us(2) /* Now define how each digit maps to the segments: @@ -326,8 +324,8 @@ void init_lcd(void) { void show_batt_cgg1(void) { uint16_t battery_level = 0; - if (measured_data.battery_mv > MIN_VBAT_MV) { - battery_level = ((measured_data.battery_mv - MIN_VBAT_MV)*10)/((MAX_VBAT_MV - MIN_VBAT_MV)/100); + if (measured_data.average_battery_mv > MIN_VBAT_MV) { + battery_level = ((measured_data.average_battery_mv - MIN_VBAT_MV)*10)/((MAX_VBAT_MV - MIN_VBAT_MV)/100); if (battery_level > 995) battery_level = 995; } @@ -338,6 +336,7 @@ _attribute_ram_code_ void update_lcd(void){ if (!stage_lcd) { if (memcmp(&display_cmp_buff, &display_buff, sizeof(display_buff))) { memcpy(&display_cmp_buff, &display_buff, sizeof(display_buff)); + lcd_flg.b.send_notify = lcd_flg.b.notify_on; // set flag LCD for send notify if (lcd_refresh_cnt) { lcd_refresh_cnt--; flg_lcd_init = 0; diff --git a/src/epd_cgg1n.c b/src/epd_cgg1n.c index 35606203..762e00f0 100644 --- a/src/epd_cgg1n.c +++ b/src/epd_cgg1n.c @@ -95,8 +95,6 @@ const uint8_t digits[16][DEF_EPD_SUMBOL_SIGMENTS + 1] = { {1, 2, 8, 9, 10, 11, 12, 13, 0, 0, 0, 0, 0, 0} // F }; -RAM uint8_t display_buff[16]; -RAM uint8_t display_cmp_buff[16]; RAM uint8_t stage_lcd; //RAM uint8_t flg_lcd_init; RAM uint8_t lcd_refresh_cnt; @@ -110,8 +108,9 @@ const uint8_t T_LUT_init[14] = {0x082, 0x068, 0x050, 0x0E8, 0x0D0, 0x0A8, 0x065, const uint8_t T_LUT_work[9] = {0x082, 0x080, 0x000, 0x0C0, 0x080, 0x080, 0x062, 0x0AC, 0x02B}; //const uint8_t T_LUT_test[16] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00}; -#define delay_SPI_end_cycle() cpu_stall_wakeup_by_timer0((CLOCK_SYS_CLOCK_1US*15)/10) // real clk 4.4 + 4.4 us : 114 kHz) -#define delay_EPD_SCL_pulse() cpu_stall_wakeup_by_timer0((CLOCK_SYS_CLOCK_1US*15)/10) // real clk 4.4 + 4.4 us : 114 kHz) +#define delay_SPI_end_cycle() sleep_us(2) +#define delay_EPD_SCL_pulse() sleep_us(2) + /* 0x00 = " " * 0x20 = "°Г" * 0x40 = " -" @@ -357,6 +356,7 @@ _attribute_ram_code_ void update_lcd(void){ if (!stage_lcd) { if (memcmp(&display_cmp_buff, &display_buff, sizeof(display_buff))) { memcpy(&display_cmp_buff, &display_buff, sizeof(display_buff)); + lcd_flg.b.send_notify = lcd_flg.b.notify_on; // set flag LCD for send notify if (lcd_refresh_cnt) { lcd_refresh_cnt--; } else { diff --git a/src/epd_mho_c401.c b/src/epd_mho_c401.c index b5b80e88..e9f4f27e 100644 --- a/src/epd_mho_c401.c +++ b/src/epd_mho_c401.c @@ -4,14 +4,13 @@ #if DEVICE_TYPE == DEVICE_MHO_C401 /* Based on source: https://github.com/znanev/ATC_MiThermometer */ #include "app.h" +#include "lcd.h" #include "epd.h" #include "drivers/8258/pm.h" #include "drivers/8258/timer.h" #define DEF_EPD_REFRESH_CNT 32 -RAM uint8_t display_buff[18]; -RAM uint8_t display_cmp_buff[18]; RAM uint8_t stage_lcd; RAM uint8_t flg_lcd_init; RAM uint8_t lcd_refresh_cnt; @@ -39,8 +38,8 @@ const uint8_t bottom_right[22] = {7, 7, 6, 5, 2, 0, 2, 3, 0, 2, 1, 7, 2, 6, 7, 4 // These values closely reproduce times captured with logic analyser //#define delay_SPI_end_cycle() pm_wait_us(3) // 1.5 us //#define delay_EPD_SCL_pulse() pm_wait_us(3) // 1.5 us -#define delay_SPI_end_cycle() cpu_stall_wakeup_by_timer0((CLOCK_SYS_CLOCK_1US*15)/10) // real clk 4.4 + 4.4 us : 114 kHz) -#define delay_EPD_SCL_pulse() cpu_stall_wakeup_by_timer0((CLOCK_SYS_CLOCK_1US*15)/10) // real clk 4.4 + 4.4 us : 114 kHz) +#define delay_SPI_end_cycle() sleep_us(2) +#define delay_EPD_SCL_pulse() sleep_us(2) /* Now define how each digit maps to the segments: @@ -315,6 +314,7 @@ _attribute_ram_code_ void update_lcd(void){ if (!stage_lcd) { if (memcmp(&display_cmp_buff, &display_buff, sizeof(display_buff))) { memcpy(&display_cmp_buff, &display_buff, sizeof(display_buff)); + lcd_flg.b.send_notify = lcd_flg.b.notify_on; // set flag LCD for send notify if (lcd_refresh_cnt) { lcd_refresh_cnt--; flg_lcd_init = 0; diff --git a/src/epd_mho_c401n.c b/src/epd_mho_c401n.c index 3267fc9f..e509b3b8 100644 --- a/src/epd_mho_c401n.c +++ b/src/epd_mho_c401n.c @@ -43,8 +43,6 @@ None: 0.1..0.3, 0.5..0.7, 2.3..2.7, 4.3..4.7, 5.1, 5,3, 5.5, 5.7, 6.1, 6.3, 6.7, #define DEF_EPD_REFRESH_CNT 2048 -RAM uint8_t display_buff[16]; -RAM uint8_t display_cmp_buff[16]; RAM uint8_t stage_lcd; RAM uint8_t epd_updated; RAM uint16_t lcd_refresh_cnt; @@ -64,8 +62,8 @@ const uint8_t bottom_left[22] = {1, 7, 2, 2, 2, 1, 2, 0, 1, 5, 1, 0, 1, 1, const uint8_t bottom_right[22]= {3, 7, 4, 2, 4, 1, 4, 0, 3, 5, 3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 6}; // These values closely reproduce times captured with logic analyser -#define delay_SPI_end_cycle() cpu_stall_wakeup_by_timer0((CLOCK_SYS_CLOCK_1US*12)/10) // real clk 4.4 + 4.4 us : 114 kHz) -#define delay_EPD_SCL_pulse() cpu_stall_wakeup_by_timer0((CLOCK_SYS_CLOCK_1US*12)/10) // real clk 4.4 + 4.4 us : 114 kHz) +#define delay_SPI_end_cycle() sleep_us(2) +#define delay_EPD_SCL_pulse() sleep_us(2) /* Now define how each digit maps to the segments: @@ -108,7 +106,8 @@ const uint8_t digits[16][11] = { * 0xA0 = "°C" * 0xC0 = " =" * 0xE0 = "°E" */ -_attribute_ram_code_ void show_temp_symbol(uint8_t symbol) { +_attribute_ram_code_ +void show_temp_symbol(uint8_t symbol) { if (symbol & 0x20) display_buff[14] |= BIT(4); // "Г", "%", "( )", "." else @@ -130,7 +129,8 @@ _attribute_ram_code_ void show_temp_symbol(uint8_t symbol) { * 5 = "vVv" happy * 6 = "^-^" sad * 7 = "oOo" */ -_attribute_ram_code_ void show_smiley(uint8_t state){ +_attribute_ram_code_ +void show_smiley(uint8_t state){ // off display_buff[5] &= ~(BIT(2) | BIT(4) | BIT(6)); // do not reset % display_buff[6] = 0; @@ -170,14 +170,16 @@ _attribute_ram_code_ void show_smiley(uint8_t state){ } } -_attribute_ram_code_ void show_battery_symbol(bool state){ +_attribute_ram_code_ +void show_battery_symbol(bool state){ if (state) display_buff[14] |= BIT(6); else display_buff[14] &= ~BIT(6); } -_attribute_ram_code_ void show_ble_symbol(bool state){ +_attribute_ram_code_ +void show_ble_symbol(bool state){ if (state) display_buff[0] |= BIT(4); // "*" else @@ -189,10 +191,12 @@ void show_connected_symbol(bool state){ display_buff[0] |= BIT(0); else display_buff[0] &= ~BIT(0); - tim_last_chow = clock_time() - min_step_time_update_lcd - (8*CLOCK_16M_SYS_TIMER_CLK_1MS); + SET_LCD_UPDATE(); } -_attribute_ram_code_ __attribute__((optimize("-Os"))) static void epd_set_digit(uint8_t *buf, uint8_t digit, const uint8_t *segments) { +_attribute_ram_code_ +__attribute__((optimize("-Os"))) +static void epd_set_digit(uint8_t *buf, uint8_t digit, const uint8_t *segments) { // set the segments, there are up to 11 segments in a digit int segment_byte; int segment_bit; @@ -213,7 +217,9 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) static void epd_set_digit( } /* number in 0.1 (-995..19995), Show: -99 .. -9.9 .. 199.9 .. 1999 */ -_attribute_ram_code_ __attribute__((optimize("-Os"))) void show_big_number_x10(int16_t number){ +_attribute_ram_code_ +__attribute__((optimize("-Os"))) +void show_big_number_x10(int16_t number){ display_buff[8] = 0; display_buff[9] = 0; display_buff[10] = 0; @@ -258,7 +264,9 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) void show_big_number_x10(i } /* -9 .. 99 */ -_attribute_ram_code_ __attribute__((optimize("-Os"))) void show_small_number(int16_t number, bool percent){ +_attribute_ram_code_ +__attribute__((optimize("-Os"))) +void show_small_number(int16_t number, bool percent){ display_buff[1] = 0; display_buff[2] = 0; display_buff[3] = 0; @@ -288,7 +296,9 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) void show_small_number(int } } -_attribute_ram_code_ __attribute__((optimize("-Os"))) static void transmit(uint8_t cd, uint8_t data_to_send) { +_attribute_ram_code_ +__attribute__((optimize("-Os"))) +static void transmit(uint8_t cd, uint8_t data_to_send) { gpio_write(EPD_SCL, LOW); gpio_write(EPD_CSB, LOW); delay_EPD_SCL_pulse(); @@ -323,7 +333,8 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) static void transmit(uint8 delay_SPI_end_cycle(); } -_attribute_ram_code_ static void transmit_blk(uint8_t cd, const uint8_t * pdata, size_t size_data) { +_attribute_ram_code_ +static void transmit_blk(uint8_t cd, const uint8_t * pdata, size_t size_data) { for (int i = 0; i < size_data; i++) transmit(cd, pdata[i]); } @@ -340,7 +351,8 @@ void init_lcd(void) { } -_attribute_ram_code_ void update_lcd(void){ +_attribute_ram_code_ +void update_lcd(void){ if (!stage_lcd) { if (memcmp(&display_cmp_buff, &display_buff, sizeof(display_buff))) { memcpy(&display_cmp_buff, &display_buff, sizeof(display_buff)); @@ -348,12 +360,14 @@ _attribute_ram_code_ void update_lcd(void){ lcd_refresh_cnt--; else if(ble_connected == 0) init_lcd(); // pulse RST_N low for 110 microseconds + lcd_flg.b.send_notify = lcd_flg.b.notify_on; // set flag LCD for send notify stage_lcd = 1; } } } -_attribute_ram_code_ __attribute__((optimize("-Os"))) int task_lcd(void) { +_attribute_ram_code_ +__attribute__((optimize("-Os"))) int task_lcd(void) { if (gpio_read(EPD_BUSY)) { switch (stage_lcd) { case 1: // Update/Init, stage 1 @@ -397,7 +411,8 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) int task_lcd(void) { } #if USE_CLOCK -_attribute_ram_code_ void show_clock(void) { +_attribute_ram_code_ +void show_clock(void) { uint32_t tmp = utc_time_sec / 60; uint32_t min = tmp % 60; uint32_t hrs = tmp / 60 % 24; diff --git a/src/flash_eep.h b/src/flash_eep.h index aa2f60f9..9ba61ff2 100644 --- a/src/flash_eep.h +++ b/src/flash_eep.h @@ -12,10 +12,16 @@ extern "C" { #endif -//#include -//#include -//#include - +// EEPROM IDs +#define EEP_ID_CFG (0x0CFC) // EEP ID config data +#define EEP_ID_TRG (0x0DFE) // EEP ID trigger data +#define EEP_ID_RPC (0x0DF5) // EEP ID reed switch pulse counter +#define EEP_ID_PCD (0xC0DE) // EEP ID pincode +#define EEP_ID_CMF (0x0FCC) // EEP ID comfort data +#define EEP_ID_DVN (0x0DB5) // EEP ID device name +#define EEP_ID_TIM (0x0ADA) // EEP ID time adjust +#define EEP_ID_KEY (0xBEAC) // EEP ID bkey +#define EEP_ID_HWV (0x1234) // EEP ID Mi HW version #define EEP_ID_VER (0x5555) // EEP ID blk: unsigned int = minimum supported version //----------------------------------------------------------------------------- #define FLASH_BASE_ADDR 0x00000000 diff --git a/src/ha_ble_beacon.c b/src/ha_ble_beacon.c index ec7e0654..41ca9b76 100644 --- a/src/ha_ble_beacon.c +++ b/src/ha_ble_beacon.c @@ -89,7 +89,7 @@ void ha_ble_encrypt_data_beacon(void) { p->swtch = trg.flg.trg_output; p->v_st = HaBleType_uint + sizeof(p->v_id) + sizeof(p->battery_mv); p->v_id = HaBleID_voltage; - p->battery_mv = measured_data.battery_mv; // x mV + p->battery_mv = measured_data.average_battery_mv; // x mV ha_ble_encrypt(buf, sizeof(adv_ha_ble_data2_t)); } } @@ -149,7 +149,7 @@ void ha_ble_data_beacon(void) { p->data.swtch = trg.flg.trg_output; p->data.v_st = HaBleType_uint + sizeof(p->data.v_id) + sizeof(p->data.battery_mv); p->data.v_id = HaBleID_voltage; - p->data.battery_mv = measured_data.battery_mv; // x mV + p->data.battery_mv = measured_data.average_battery_mv; // x mV } } diff --git a/src/i2c.c b/src/i2c.c index 0bcdd2e7..298cc522 100644 --- a/src/i2c.c +++ b/src/i2c.c @@ -31,9 +31,12 @@ void init_i2c(void){ int scan_i2c_addr(int address) { if ((reg_clk_en0 & FLD_CLK0_I2C_EN)==0) init_i2c(); + uint8_t r = reg_i2c_speed; + reg_i2c_speed = (uint8_t)(CLOCK_SYS_CLOCK_HZ/(4*100000)); // 100 kHz reg_i2c_id = (uint8_t) address; reg_i2c_ctrl = FLD_I2C_CMD_START | FLD_I2C_CMD_ID | FLD_I2C_CMD_STOP; while (reg_i2c_status & FLD_I2C_CMD_BUSY); + reg_i2c_speed = r; return ((reg_i2c_status & FLD_I2C_NAK)? 0 : address); } @@ -91,7 +94,6 @@ int read_i2c_byte_addr(uint8_t i2c_addr, uint8_t reg_addr, uint8_t * dataBuf, ui if ((reg_clk_en0 & FLD_CLK0_I2C_EN)==0) init_i2c(); //unsigned char r = irq_disable(); - //reg_i2c_speed = (uint8_t)(CLOCK_SYS_CLOCK_HZ/(4*125000)); // 125 kHz reg_i2c_id = i2c_addr; reg_i2c_adr = reg_addr; reg_i2c_ctrl = FLD_I2C_CMD_START | FLD_I2C_CMD_ID | FLD_I2C_CMD_ADDR; @@ -101,8 +103,6 @@ int read_i2c_byte_addr(uint8_t i2c_addr, uint8_t reg_addr, uint8_t * dataBuf, ui // Start By Master Read, Write Slave Address, Read data first byte reg_rst0 = FLD_RST0_I2C; reg_rst0 = 0; - //while(reg_i2c_status & FLD_I2C_CMD_BUSY); - //reg_i2c_speed = (uint8_t)(CLOCK_SYS_CLOCK_HZ/(4*125000)); // 125 kHz reg_i2c_id = i2c_addr | FLD_I2C_WRITE_READ_BIT; reg_i2c_ctrl = FLD_I2C_CMD_START | FLD_I2C_CMD_ID | FLD_I2C_CMD_READ_ID; while(reg_i2c_status & FLD_I2C_CMD_BUSY); diff --git a/src/lcd.c b/src/lcd.c index 524e4bc9..e536912e 100644 --- a/src/lcd.c +++ b/src/lcd.c @@ -1,333 +1,186 @@ +/* + * lcd.c + * + * Created on: 10.03.2023 + * Author: pvvx + */ #include #include "tl_common.h" #include "app_config.h" -#if DEVICE_TYPE == DEVICE_LYWSD03MMC +#if(DEVICE_TYPE != DEVICE_MJWSD05MMC) #include "drivers.h" #include "drivers/8258/gpio_8258.h" #include "app.h" #include "i2c.h" -#include "lcd.h" - -/* t,H,h,L,o,i 0xe2,0x67,0x66,0xe0,0xC6,0x40 */ -#define LCD_SYM_H 0x67 // "H" -#define LCD_SYM_i 0x40 // "i" -#define LCD_SYM_L 0xE0 // "L" -#define LCD_SYM_o 0xC6 // "o" - -#define LCD_SYM_BLE 0x10 // connect -#define LCD_SYM_BAT 0x08 // battery - -RAM uint8_t lcd_i2c_addr; - -const uint8_t lcd_init_cmd_b14[] = {0x80,0x3B,0x80,0x02,0x80,0x0F,0x80,0x95,0x80,0x88,0x80,0x88,0x80,0x88,0x80,0x88,0x80,0x19,0x80,0x28,0x80,0xE3,0x80,0x11}; - // {0x80,0x40,0xC0,byte1,0xC0,byte2,0xC0,byte3,0xC0,byte4,0xC0,byte5,0xC0,byte6}; -const uint8_t lcd_init_clr_b14[] = {0x80,0x40,0xC0,0,0xC0,0,0xC0,0,0xC0,0,0xC0,0,0xC0,0,0xC0,0,0xC0,0}; -const uint8_t lcd_init_clr_b19[] = {0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00}; - -RAM uint8_t display_buff[6]; -RAM uint8_t display_cmp_buff[6]; - -typedef struct __attribute__((packed)) _dma_uart_buf_t { - volatile uint32_t dma_len; - uint32_t head; - uint8_t start; - uint8_t data[6]; - uint8_t chk; - uint8_t end; -} dma_uart_buf_t; - -RAM dma_uart_buf_t utxb; - -/* 0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F*/ -const uint8_t display_numbers[] = {0xf5,0x05,0xd3,0x97,0x27,0xb6,0xf6,0x15,0xf7,0xb7, 0x77,0xe6,0xf0,0xc7,0xf2,0x72}; - -static _attribute_ram_code_ uint8_t reverse(uint8_t revByte) { - revByte = (revByte & 0xF0) >> 4 | (revByte & 0x0F) << 4; - revByte = (revByte & 0xCC) >> 2 | (revByte & 0x33) << 2; - revByte = (revByte & 0xAA) >> 1 | (revByte & 0x55) << 1; - return revByte; -} - -static void lcd_send_i2c_byte(uint8_t cmd) { - if ((reg_clk_en0 & FLD_CLK0_I2C_EN)==0) - init_i2c(); - reg_i2c_id = lcd_i2c_addr; - reg_i2c_adr = cmd; - reg_i2c_ctrl = FLD_I2C_CMD_START | FLD_I2C_CMD_ID | FLD_I2C_CMD_ADDR | FLD_I2C_CMD_STOP; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); -} - -static void lcd_send_i2c_buf(uint8_t * dataBuf, uint32_t dataLen) { - if ((reg_clk_en0 & FLD_CLK0_I2C_EN)==0) - init_i2c(); - uint8_t * p = dataBuf; - reg_i2c_id = lcd_i2c_addr; - reg_i2c_ctrl = FLD_I2C_CMD_START | FLD_I2C_CMD_ID; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - while (dataLen--) { - reg_i2c_do = *p++; - reg_i2c_ctrl = FLD_I2C_CMD_DO; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - } - reg_i2c_ctrl = FLD_I2C_CMD_STOP; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); -} - -// UART 38400 BAUD -#define UART_BAUD 38400 -#if CLOCK_SYS_CLOCK_HZ == 16000000 -#define uartCLKdiv 51 // 16000000/(7+1)/(51+1)=38461.538... -#define bwpc 7 -#elif CLOCK_SYS_CLOCK_HZ == 24000000 -#define uartCLKdiv 124 // 24000000/(4+1)/(124+1)=38400 -#define bwpc 4 -#elif CLOCK_SYS_CLOCK_HZ == 32000000 -#define uartCLKdiv 103 // 32000000/(7+1)/(103+1)=38461.538... -#define bwpc 7 -#elif CLOCK_SYS_CLOCK_HZ == 48000000 -#define uartCLKdiv 124 // 48000000/(9+1)/(124+1)=38400 -#define bwpc 9 +#if USE_RTC +#include "rtc.h" #endif +#include "lcd.h" +#include "ble.h" +#include "battery.h" -_attribute_ram_code_ void lcd_send_uart(void) { - // init uart - reg_clk_en0 |= FLD_CLK0_UART_EN; - ///reg_clk_en1 |= FLD_CLK1_DMA_EN; - uart_reset(); - // reg_uart_clk_div/reg_uart_ctrl0 - REG_ADDR32(0x094) = MASK_VAL(FLD_UART_CLK_DIV, uartCLKdiv, FLD_UART_CLK_DIV_EN, 1) - | ((MASK_VAL(FLD_UART_BPWC, bwpc) | (FLD_UART_TX_DMA_EN)) << 16) // set bit width, enable UART DMA mode - | ((MASK_VAL(FLD_UART_CTRL1_STOP_BIT, 0)) << 24) // 00: 1 bit, 01: 1.5bit 1x: 2bits; - ; - // reg_dma1_addr/reg_dma1_ctrl - REG_ADDR32(0xC04) = (unsigned short)((u32)(&utxb)) //set tx buffer address - | (((sizeof(utxb)+15)>>4) << 16); //set tx buffer size - ///reg_dma1_addrHi = 0x04; (in sdk init?) - reg_dma_chn_en |= FLD_DMA_CHN_UART_TX; - ///reg_dma_chn_irq_msk |= FLD_DMA_IRQ_UART_TX; - - // GPIO_PD7 set TX UART pin - REG_ADDR8(0x5AF) = (REG_ADDR8(0x5AF) & (~(BIT(7)|BIT(6)))) | BIT(7); - BM_CLR(reg_gpio_func(UART_TX_PD7), UART_TX_PD7 & 0xff); - /// gpio_set_input_en(UART_TX_PD7, 1); ??? +//RAM uint8_t show_stage; // count/stage update lcd code buffer +//RAM uint32_t chow_ext_sec; // count show validity time, in sec - // start send DMA - reg_dma_tx_rdy0 |= FLD_DMA_CHN_UART_TX; // start tx - // wait send (3.35 ms), sleep? - pm_wait_us(3330); // 13 bytes * 10 bits / 38400 baud = 0.0033854 sec = 3.4 ms power ~3 mA - //while (reg_dma_tx_rdy0 & FLD_DMA_CHN_UART_TX); ? - while (!(reg_uart_status1 & FLD_UART_TX_DONE)); - // set low/off power UART - reg_uart_clk_div = 0; -} +//RAM uint32_t min_step_time_update_lcd; // = cfg.min_step_time_update_lcd * 0.05 sec +//RAM uint32_t tim_last_chow; // timer show lcd >= 1.5 sec +RAM lcd_flg_t lcd_flg; +RAM uint8_t display_buff[LCD_BUF_SIZE], display_cmp_buff[LCD_BUF_SIZE]; -_attribute_ram_code_ void send_to_lcd(void){ - unsigned int buff_index; - uint8_t * p = display_buff; - if (lcd_i2c_addr) { - if ((reg_clk_en0 & FLD_CLK0_I2C_EN)==0) - init_i2c(); - else { - gpio_setup_up_down_resistor(I2C_SCL, PM_PIN_PULLUP_10K); - gpio_setup_up_down_resistor(I2C_SDA, PM_PIN_PULLUP_10K); - } - reg_i2c_id = lcd_i2c_addr; - - if (lcd_i2c_addr == (B14_I2C_ADDR << 1)) { - // B1.4, B1.7, B2.0 - reg_i2c_adr_dat = 0x4080; - reg_i2c_ctrl = FLD_I2C_CMD_START | FLD_I2C_CMD_ID | FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - reg_i2c_adr = 0xC0; - for(buff_index = 0; buff_index < sizeof(display_buff); buff_index++) { - reg_i2c_do = *p++; - reg_i2c_ctrl = FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - } - reg_i2c_ctrl = FLD_I2C_CMD_STOP; - } else { // (lcd_i2c_addr == (B19_I2C_ADDR << 1)) - // B1.9 - reg_i2c_adr = 0x04; - reg_i2c_do = reverse(*p++); - reg_i2c_di = reverse(*p++); - reg_i2c_ctrl = FLD_I2C_CMD_ID | FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO | FLD_I2C_CMD_DI | FLD_I2C_CMD_START; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - reg_i2c_adr_dat = 0; - reg_i2c_ctrl = FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - reg_i2c_adr = reverse(*p++); - reg_i2c_do = reverse(*p++); - reg_i2c_ctrl = FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - reg_i2c_adr_dat = 0; - reg_i2c_ctrl = FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - reg_i2c_adr = reverse(*p++); - reg_i2c_do = reverse(*p); - reg_i2c_ctrl = FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO | FLD_I2C_CMD_STOP; - } - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - } else { - // B1.6 (UART LCD) - utxb.data[5] = *p++; - utxb.data[4] = *p++; - utxb.data[3] = *p++; - utxb.data[2] = *p++; - utxb.data[1] = *p++; - utxb.data[0] = *p; - utxb.chk = utxb.data[0]^utxb.data[1]^utxb.data[2]^utxb.data[3]^utxb.data[4]^utxb.data[5]; - utxb.dma_len = sizeof(utxb) - sizeof(utxb.dma_len); - lcd_send_uart(); - } -} - -void init_lcd(void){ - lcd_i2c_addr = (uint8_t) scan_i2c_addr(B14_I2C_ADDR << 1); - if (lcd_i2c_addr) { // B1.4, B1.7, B2.0 -// GPIO_PB6 set in app_config.h! -// gpio_setup_up_down_resistor(GPIO_PB6, PM_PIN_PULLUP_10K); // LCD on low temp needs this, its an unknown pin going to the LCD controller chip - pm_wait_ms(50); - lcd_send_i2c_buf((uint8_t *) lcd_init_cmd_b14, sizeof(lcd_init_cmd_b14)); - lcd_send_i2c_buf((uint8_t *) lcd_init_clr_b14, sizeof(lcd_init_clr_b14)); - return; - } - lcd_i2c_addr = (uint8_t) scan_i2c_addr(B19_I2C_ADDR << 1); - if (lcd_i2c_addr) { // B1.9 - lcd_send_i2c_byte(0xEA); // Set IC Operation(ICSET): Software Reset, Internal oscillator circuit - sleep_us(240); - lcd_send_i2c_byte(0xA4); // Display control (DISCTL): Normal mode, FRAME flip, Power save mode 1 - lcd_send_i2c_byte(0x9C); // ? Address set (ADSET): 0x1C ? - lcd_send_i2c_byte(0xAC); // Display control (DISCTL): Power save mode 1, FRAME flip, Power save mode 1 - lcd_send_i2c_byte(0xBC); // Display control (DISCTL): Power save mode 3, FRAME flip, Power save mode 1 - lcd_send_i2c_byte(0xF0); // Blink control (BLKCTL): Off - lcd_send_i2c_byte(0xFC); // All pixel control (APCTL): Normal - lcd_send_i2c_buf((uint8_t *) lcd_init_clr_b19, sizeof(lcd_init_clr_b19)); - lcd_send_i2c_byte(0xC8); // Mode Set (MODE SET): Display ON, 1/3 Bias - return; - } - // B1.6 (UART), lcd_i2c_addr = 0 - // utxb.dma_len = 0; - // utxb.head = 0; - utxb.start = 0xAA; - // utxb.data = {0}; - utxb.end = 0x55; -} - -_attribute_ram_code_ void update_lcd(){ +#if (!USE_EPD) +_attribute_ram_code_ +void update_lcd(void){ if (memcmp(&display_cmp_buff, &display_buff, sizeof(display_buff))) { send_to_lcd(); memcpy(&display_cmp_buff, &display_buff, sizeof(display_buff)); + lcd_flg.b.send_notify = lcd_flg.b.notify_on; // set flag LCD for send notify } } -/* 0x00 = " " - * 0x20 = "°Г" - * 0x40 = " -" - * 0x60 = "°F" - * 0x80 = " _" - * 0xA0 = "°C" - * 0xC0 = " =" - * 0xE0 = "°E" */ -_attribute_ram_code_ void show_temp_symbol(uint8_t symbol) { - display_buff[2] &= ~0xE0; - display_buff[2] |= symbol & 0xE0; -} -/* 0 = " " off, - * 1 = " ^-^ " - * 2 = " -^- " - * 3 = " ooo " - * 4 = "( )" - * 5 = "(^-^)" happy - * 6 = "(-^-)" sad - * 7 = "(ooo)" */ -_attribute_ram_code_ void show_smiley(uint8_t state){ - display_buff[2] &= ~0x07; - display_buff[2] |= state & 0x07; -} - -_attribute_ram_code_ void show_ble_symbol(bool state){ - if (state) - display_buff[2] |= LCD_SYM_BLE; - else - display_buff[2] &= ~LCD_SYM_BLE; -} +#endif -_attribute_ram_code_ void show_battery_symbol(bool state){ - if (state) - display_buff[1] |= LCD_SYM_BAT; - else - display_buff[1] &= ~LCD_SYM_BAT; +_attribute_ram_code_ +uint8_t is_comfort(int16_t t, uint16_t h) { + uint8_t ret = SMILE_SAD; + if (t >= cmf.t[0] && t <= cmf.t[1] && h >= cmf.h[0] && h <= cmf.h[1]) + ret = SMILE_HAPPY; + return ret; } -/* number in 0.1 (-995..19995), Show: -99 .. -9.9 .. 199.9 .. 1999 */ -_attribute_ram_code_ __attribute__((optimize("-Os"))) void show_big_number_x10(int16_t number){ -// display_buff[4] = point?0x08:0x00; - if (number > 19995) { - display_buff[3] = 0; - display_buff[4] = LCD_SYM_i; // "i" - display_buff[5] = LCD_SYM_H; // "H" - } else if (number < -995) { - display_buff[3] = 0; - display_buff[4] = LCD_SYM_o; // "o" - display_buff[5] = LCD_SYM_L; // "L" +_attribute_ram_code_ +__attribute__((optimize("-Os"))) +void lcd(void) { + bool set_small_number_and_bat = true; + bool show_ext = lcd_flg.chow_ext_ut >= utc_time_sec; + if(cfg.flg.show_time_smile || cfg.flg.show_batt_enabled || show_ext) + lcd_flg.update_next_measure = 0; + else + lcd_flg.update_next_measure = 1; + if (show_ext && (lcd_flg.show_stage & 2)) { // show ext data + if (lcd_flg.show_stage & 1) { // stage blinking or show battery or clock + if (cfg.flg.show_batt_enabled +#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) +#else + || measured_data.battery_level <= 15 +#endif + ) { // Battery +#if (DEVICE_TYPE != DEVICE_CGDK2) + show_smiley(0); // stage show battery +#endif + show_battery_symbol(1); +#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) +#if DEVICE_TYPE == DEVICE_CGG1 + show_batt_cgg1(); +#else + show_batt_cgdk2(); +#endif +#else + show_small_number((measured_data.battery_level >= 100) ? 99 : measured_data.battery_level, 1); +#endif // (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) + set_small_number_and_bat = false; + } else if (cfg.flg.show_time_smile) { // show clock +#if USE_CLOCK + show_clock(); // stage clock + show_ble_symbol(ble_connected); + return; +#else +#if (DEVICE_TYPE != DEVICE_CGDK2) + show_smiley(0); // stage clock/blinking and blinking on +#endif +#endif + } +#if (DEVICE_TYPE != DEVICE_CGDK2) + else + show_smiley(*((uint8_t *) &ext.flg)); +#endif + } +#if (DEVICE_TYPE != DEVICE_CGDK2) + else + show_smiley(*((uint8_t *) &ext.flg)); +#endif + if (set_small_number_and_bat) { + show_battery_symbol(ext.flg.battery); +#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) + show_small_number_x10(ext.small_number, ext.flg.percent_on); +#else + show_small_number(ext.small_number, ext.flg.percent_on); +#endif + } + show_temp_symbol(*((uint8_t *) &ext.flg)); + show_big_number_x10(ext.big_number); } else { - display_buff[5] = 0; - /* number: -995..19995 */ - if (number > 1995 || number < -95) { - display_buff[4] = 0; // no point, show: -99..1999 - if (number < 0){ - number = -number; - display_buff[5] = 2; // "-" + if (lcd_flg.show_stage & 1) { // stage clock/blinking or show battery +#if USE_CLOCK + if (cfg.flg.show_time_smile && (lcd_flg.show_stage & 2)) { + show_clock(); // stage clock + show_ble_symbol(ble_connected); + return; } - number = (number / 10) + ((number % 10) > 5); // round(div 10) - } else { // show: -9.9..199.9 - display_buff[4] = 0x08; // point, - if (number < 0){ - number = -number; - display_buff[5] = 2; // "-" +#endif + if (cfg.flg.show_batt_enabled +#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) +#else + || measured_data.battery_level <= 15 +#endif + ) { // Battery +#if (DEVICE_TYPE != DEVICE_CGDK2) + show_smiley(0); // stage show battery +#endif + show_battery_symbol(1); +#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) +#if DEVICE_TYPE == DEVICE_CGG1 + show_batt_cgg1(); +#else + show_batt_cgdk2(); +#endif +#else + show_small_number((measured_data.battery_level >= 100) ? 99 : measured_data.battery_level, 1); +#endif // (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) + set_small_number_and_bat = false; + } else if (cfg.flg.show_time_smile) { // show clock +#if USE_CLOCK + show_clock(); // stage clock + show_ble_symbol(ble_connected); + return; +#else +#if (DEVICE_TYPE != DEVICE_CGDK2) + show_smiley(0); // stage blinking and blinking on +#endif +#endif + } else { +#if (DEVICE_TYPE != DEVICE_CGDK2) + if (cfg.flg.comfort_smiley) { // comfort on + show_smiley(is_comfort(measured_data.temp, measured_data.humi)); + } else + show_smiley(cfg.flg2.smiley); +#endif } + } else { +#if (DEVICE_TYPE != DEVICE_CGDK2) + if (cfg.flg.comfort_smiley) { // comfort on + show_smiley(is_comfort(measured_data.temp, measured_data.humi)); + } else + show_smiley(cfg.flg2.smiley); +#endif } - /* number: -99..1999 */ - if (number > 999) display_buff[5] |= 0x08; // "1" 1000..1999 - if (number > 99) display_buff[5] |= display_numbers[number / 100 % 10]; - if (number > 9) display_buff[4] |= display_numbers[number / 10 % 10]; - else display_buff[4] |= 0xF5; // "0" - display_buff[3] = display_numbers[number %10]; - } -} - -/* -9 .. 99 */ -_attribute_ram_code_ __attribute__((optimize("-Os"))) void show_small_number(int16_t number, bool percent){ - display_buff[1] = display_buff[1] & 0x08; // and battery - display_buff[0] = percent?0x08:0x00; - if (number > 99) { - display_buff[0] |= LCD_SYM_i; // "i" - display_buff[1] |= LCD_SYM_H; // "H" - } else if (number < -9) { - display_buff[0] |= LCD_SYM_o; // "o" - display_buff[1] |= LCD_SYM_L; // "L" - } else { - if (number < 0) { - number = -number; - display_buff[1] = 2; // "-" + if (set_small_number_and_bat) { +#if (DEVICE_TYPE == DEVICE_CGG1) || (DEVICE_TYPE == DEVICE_CGDK2) + show_battery_symbol(!cfg.flg.show_batt_enabled); + show_small_number_x10(measured_data.humi_x01, 1); +#else + show_battery_symbol(0); + show_small_number(measured_data.humi_x1, 1); +#endif + } + if (cfg.flg.temp_F_or_C) { + show_temp_symbol(TMP_SYM_F); // "°F" + show_big_number_x10((((measured_data.temp / 5) * 9) + 3200) / 10); // convert C to F + } else { + show_temp_symbol(TMP_SYM_C); // "°C" + show_big_number_x10(measured_data.temp_x01); } - if (number > 9) display_buff[1] |= display_numbers[number / 10 % 10]; - display_buff[0] |= display_numbers[number %10]; } + show_ble_symbol(ble_connected); } -#if USE_CLOCK -_attribute_ram_code_ 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] = display_numbers[hrs % 10]; - display_buff[4] = display_numbers[hrs / 10 % 10]; - display_buff[5] = 0; -} -#endif // USE_CLOCK - -#endif // DEVICE_TYPE == DEVICE_LYWSD03MMC +#endif // (DEVICE_TYPE != DEVICE_MJWSD05MMC) diff --git a/src/lcd.h b/src/lcd.h index 02dbfef5..3101a1d4 100644 --- a/src/lcd.h +++ b/src/lcd.h @@ -3,6 +3,30 @@ #include #include #include "app_config.h" + +typedef struct _lcd_flg_t { + uint32_t chow_ext_ut; // count chow ext.vars validity time, in sec +#if (DEVICE_TYPE != DEVICE_MJWSD05MMC) + uint32_t min_step_time_update_lcd; // = cfg.min_step_time_update_lcd * (50 * CLOCK_16M_SYS_TIMER_CLK_1MS) + uint32_t tim_last_chow; // timer show lcd >= 1.5 sec + uint8_t show_stage; // count/stage update lcd code buffer + uint8_t update_next_measure; // flag update LCD if next_measure +#endif + uint8_t update; // flag update LCD + union { + struct { + // reset all flags on disconnect + uint8_t ext_data_buf: 1; // LCD show external buffer + uint8_t notify_on: 1; // Send LCD dump if Notify on + uint8_t res: 5; + uint8_t send_notify: 1; // flag update LCD for send notify + }b; + uint8_t all_flg; + }; +} lcd_flg_t; +extern lcd_flg_t lcd_flg; + + #if (DEVICE_TYPE != DEVICE_MJWSD05MMC) /* CGG1 no symbol 'smiley' ! */ #define SMILE_HAPPY 5 // "(^-^)" happy @@ -10,16 +34,19 @@ #define TMP_SYM_C 0xA0 // "°C" #define TMP_SYM_F 0x60 // "°F" +// LCD controller I2C address #define B14_I2C_ADDR 0x3C -#define B16_I2C_ADDR 0 // UART -#define B19_I2C_ADDR 0x3E -#define CGDK2_I2C_ADDR 0x3E - -extern uint8_t lcd_i2c_addr; +#define B16_I2C_ADDR 0 // UART +#define B19_I2C_ADDR 0x3E // BU9792AFUV +#define CGDK2_I2C_ADDR 0x3E // BU9792AFUV +extern uint8_t lcd_i2c_addr; // LCD controller I2C address -void init_lcd(); -void update_lcd(); +//#define SET_LCD_UPDATE() +void lcd(void); +void init_lcd(void); +void send_to_lcd(void); +void update_lcd(void); /* 0x00 = " " * 0x20 = "°Г" * 0x40 = " -" @@ -61,32 +88,42 @@ void show_clock(void); #endif #if DEVICE_TYPE == DEVICE_MHO_C401 -extern uint8_t display_buff[18]; +#define SET_LCD_UPDATE() { lcd_flg.update = 1; lcd_flg.update_next_measure = 0; } +#define SHOW_CONNECTED_SYMBOL(a) { lcd_flg.update = 1; lcd_flg.update_next_measure = 0; } +#define LCD_BUF_SIZE 18 extern uint8_t stage_lcd; void show_small_number(int16_t number, bool percent); // -9 .. 99 int task_lcd(void); #elif DEVICE_TYPE == DEVICE_MHO_C401N -extern uint8_t display_buff[16]; +#define SET_LCD_UPDATE() { lcd_flg.update = 1; lcd_flg.update_next_measure = 0; } +#define LCD_BUF_SIZE 16 extern uint8_t stage_lcd; void show_small_number(int16_t number, bool percent); // -9 .. 99 -#define LCD_CONN_SYMBOL 1 void show_connected_symbol(bool state); +#define SHOW_CONNECTED_SYMBOL(a) show_connected_symbol(a) int task_lcd(void); #elif DEVICE_TYPE == DEVICE_CGG1 +#define SET_LCD_UPDATE() { lcd_flg.update = 1; lcd_flg.update_next_measure = 0; } +#define SHOW_CONNECTED_SYMBOL(a) { lcd_flg.update = 1; lcd_flg.update_next_measure = 0; } #if DEVICE_CGG1_ver == 2022 -extern uint8_t display_buff[16]; +#define LCD_BUF_SIZE 16 #else -extern uint8_t display_buff[18]; +#define LCD_BUF_SIZE 18 #endif extern uint8_t stage_lcd; void show_small_number_x10(int16_t number, bool percent); // -9 .. 99 int task_lcd(void); void show_batt_cgg1(void); #elif DEVICE_TYPE == DEVICE_LYWSD03MMC -extern uint8_t display_buff[6]; +#define SET_LCD_UPDATE() { lcd_flg.update = 1; lcd_flg.update_next_measure = 0; } +#define SHOW_CONNECTED_SYMBOL(a) { lcd_flg.update = 1; lcd_flg.update_next_measure = 0; } +#define LCD_BUF_SIZE 6 +extern uint8_t display_buff[LCD_BUF_SIZE], display_cmp_buff[LCD_BUF_SIZE]; void show_small_number(int16_t number, bool percent); // -9 .. 99 #elif DEVICE_TYPE == DEVICE_CGDK2 -extern uint8_t display_buff[18]; +#define LCD_BUF_SIZE 18 +#define SET_LCD_UPDATE() { lcd_flg.update = 1; lcd_flg.update_next_measure = 0; } +#define SHOW_CONNECTED_SYMBOL(a) { lcd_flg.update = 1; lcd_flg.update_next_measure = 0; } void show_batt_cgdk2(void); void show_small_number_x10(int16_t number, bool percent); // -9 .. 99 #else @@ -108,7 +145,7 @@ enum { } SCR_TYPE_ENUM; #define MJWSD05MMC_LCD_I2C_ADDR 0x3E -#define min_step_time_update_lcd (500 * CLOCK_16M_SYS_TIMER_CLK_1MS) +//#define min_step_time_update_lcd (500 * CLOCK_16M_SYS_TIMER_CLK_1MS) #define LCD_SYM_SMILEY_NONE 0 // "(^-^)" happy #define LCD_SYM_SMILEY_HAPPY 5 // "(^-^)" happy @@ -149,8 +186,13 @@ void show_ota_screen(void); void show_reboot_screen(void); #endif +extern volatile uint8_t lcd_update; +#define SET_LCD_UPDATE() lcd_flg.update = 1 +#define SHOW_CONNECTED_SYMBOL(a) lcd_flg.update = 1 + void init_lcd(void); void lcd(void); +void send_to_lcd(void); void update_lcd(void); void show_battery_symbol(bool state); void show_ble_symbol(bool state); @@ -165,8 +207,8 @@ void show_data_s2(void); void show_low_bat(void); #define LCD_BUF_SIZE 18 -//extern uint32_t min_step_time_update_lcd; // = cfg.min_step_time_update_lcd * 0.05 sec -//extern uint32_t tim_last_chow; // timer show lcd >= 1.5 sec -extern uint8_t display_buff[LCD_BUF_SIZE]; #endif // (DEVICE_TYPE == DEVICE_MJWSD05MMC) + +extern uint8_t display_buff[LCD_BUF_SIZE], display_cmp_buff[LCD_BUF_SIZE]; + diff --git a/src/lcd_cgdk2.c b/src/lcd_cgdk2.c index b35ae6d2..89b07458 100644 --- a/src/lcd_cgdk2.c +++ b/src/lcd_cgdk2.c @@ -10,8 +10,6 @@ #include "battery.h" RAM uint8_t lcd_i2c_addr; -RAM uint8_t display_buff[18]; -RAM uint8_t display_cmp_buff[18]; #define lcd_send_i2c_byte(a) send_i2c_byte(lcd_i2c_addr, a) #define lcd_send_i2c_buf(b, a) send_i2c_buf(lcd_i2c_addr, (uint8_t *) b, a) @@ -106,7 +104,14 @@ const uint8_t bottom_right[DEF_CGDK22_SUMBOL_SIGMENTS*2] = {9, 3, 17, 7, 10, 7, 3. 0xf0 - Blink control (BLKCTL): Off 4. 0xfc - All pixel control (APCTL): Normal */ -const uint8_t lcd_init_cmd[] = {0xea,0xbe,0xf0,0xfc}; +//const uint8_t lcd_init_cmd[] = {0xea,0xbe,0xf0,0xfc}; // sleep all 16.6 uA +/* LCD controller initialize +1. 0xea - Set IC Operation(ICSET): Software Reset, Internal oscillator circuit +2. 0xf0 - Blink control (BLKCTL): Off +4. 0xc0 - Mode Set (MODE SET): Display ON ? +2. 0xbc - Display control (DISCTL): Power save mode 3, FRAME flip, Power save mode 1 +*/ +const uint8_t lcd_init_cmd[] = {0xea,0xf0, 0xc0, 0xbc}; // sleep all 9.4 uA /* static void lcd_send_i2c_buf(uint8_t * dataBuf, uint32_t dataLen) { @@ -126,7 +131,8 @@ static void lcd_send_i2c_buf(uint8_t * dataBuf, uint32_t dataLen) { } */ -_attribute_ram_code_ void send_to_lcd(void){ +_attribute_ram_code_ +void send_to_lcd(void){ unsigned int buff_index; uint8_t * p = display_buff; if (lcd_i2c_addr) { @@ -161,14 +167,9 @@ void init_lcd(void){ } } -_attribute_ram_code_ void update_lcd(void){ - if (memcmp(&display_cmp_buff, &display_buff, sizeof(display_buff))) { - send_to_lcd(); - memcpy(&display_cmp_buff, &display_buff, sizeof(display_buff)); - } -} - -_attribute_ram_code_ __attribute__((optimize("-Os"))) static void cgdk22_set_digit(uint8_t *buf, uint8_t digit, const uint8_t *segments) { +_attribute_ram_code_ +__attribute__((optimize("-Os"))) +static void cgdk22_set_digit(uint8_t *buf, uint8_t digit, const uint8_t *segments) { // set the segments, there are up to 11 segments in a digit int segment_byte; int segment_bit; @@ -196,7 +197,8 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) static void cgdk22_set_dig * 0xA0 = "°C" * 0xC0 = " =" * 0xE0 = "°E" */ -_attribute_ram_code_ void show_temp_symbol(uint8_t symbol) { +_attribute_ram_code_ +void show_temp_symbol(uint8_t symbol) { if (symbol & 0x20) display_buff[17] |= BIT(6); else @@ -221,7 +223,8 @@ _attribute_ram_code_ void show_smiley(uint8_t state){ // display_buff[x] &= ~BIT(x); } */ -_attribute_ram_code_ void show_battery_symbol(bool state){ +_attribute_ram_code_ +void show_battery_symbol(bool state){ display_buff[1] &= ~(BIT(1) | BIT(2) | BIT(3) | BIT(5) | BIT(6) | BIT(7)); if (state) { display_buff[1] |= BIT(5); @@ -244,7 +247,8 @@ _attribute_ram_code_ void show_battery_symbol(bool state){ } /* CGDK22 no symbol 'ble' ! */ -_attribute_ram_code_ void show_ble_symbol(bool state){ +_attribute_ram_code_ +void show_ble_symbol(bool state){ if (state) display_buff[1] |= BIT(4); else @@ -252,7 +256,8 @@ _attribute_ram_code_ void show_ble_symbol(bool state){ } /* number in 0.1 (-995..19995), Show: -99 .. -9.9 .. 199.9 .. 1999 */ -_attribute_ram_code_ __attribute__((optimize("-Os"))) void show_big_number_x10(int16_t number){ +_attribute_ram_code_ +__attribute__((optimize("-Os"))) void show_big_number_x10(int16_t number){ display_buff[0] = 0; display_buff[1] &= ~(BIT(0)); display_buff[2] = 0; @@ -296,7 +301,8 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) void show_big_number_x10(i } /* number in 0.1 (-99..999) -> show: -9.9 .. 99.9 */ -_attribute_ram_code_ __attribute__((optimize("-Os"))) void show_small_number_x10(int16_t number, bool percent){ +_attribute_ram_code_ +__attribute__((optimize("-Os"))) void show_small_number_x10(int16_t number, bool percent){ display_buff[5] &= ~(BIT(0) | BIT(1) | BIT(2) | BIT(3)); display_buff[6] = 0; display_buff[7] = 0; @@ -343,8 +349,8 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) void show_small_number_x10 void show_batt_cgdk2(void) { uint16_t battery_level = 0; - if (measured_data.battery_mv > MIN_VBAT_MV) { - battery_level = ((measured_data.battery_mv - MIN_VBAT_MV)*10)/((MAX_VBAT_MV - MIN_VBAT_MV)/100); + if (measured_data.average_battery_mv > MIN_VBAT_MV) { + battery_level = ((measured_data.average_battery_mv - MIN_VBAT_MV)*10)/((MAX_VBAT_MV - MIN_VBAT_MV)/100); if (battery_level > 995) battery_level = 995; } @@ -352,7 +358,8 @@ void show_batt_cgdk2(void) { } #if USE_CLOCK -_attribute_ram_code_ void show_clock(void) { +_attribute_ram_code_ +void show_clock(void) { uint32_t tmp = utc_time_sec / 60; uint32_t min = tmp % 60; uint32_t hrs = tmp / 60 % 24; diff --git a/src/lcd_lywsd03mmc.c b/src/lcd_lywsd03mmc.c index feb577ca..439ab423 100644 --- a/src/lcd_lywsd03mmc.c +++ b/src/lcd_lywsd03mmc.c @@ -7,6 +7,31 @@ #include "app.h" #include "i2c.h" #include "lcd.h" +/* + * LYWSD03MMC LCD buffer: byte.bit + + --5.4-- --4.4-- --3.4-- -17.0-- BLE + | | | | | | | | | 2.4 + | 5.5 5.0 4.5 4.0 3.1 3.0 0.1 17.1 + | | | | | | | | | o 2.5 + 5.3 --5.1-- --4.1-- --3.1-- --0.2-- +--- 2.5 + | | | | | | | | | 2.5| + | 5.6 5.2 4.6 4.2 3.6 3.2 0.3 17.2 ---- 2.6 + | | | | | | | | | 2.5| + --5.7-- --4.7-- * --3.7-- -17.3-- ---- 2.7 + 4.3 + --1.4-- --0.4-- + | | | | + 2.0 2.0 1.5 1.0 0.5 0.0 + / \ / \ | | | | + 2.2( ___ 2.1 ___ )2.2 --1.1-- --0.1-- + 2.1 / \ 2.1 | | | | + ___ 1.6 1.2 0.6 0.2 % + 2.0 | | | | 0.3 + --1.7-- --0.7-- + BAT 1.3 +*/ + RAM uint8_t lcd_i2c_addr; @@ -25,10 +50,29 @@ RAM uint8_t lcd_i2c_addr; const uint8_t lcd_init_cmd_b14[] = {0x80,0x3B,0x80,0x02,0x80,0x0F,0x80,0x95,0x80,0x88,0x80,0x88,0x80,0x88,0x80,0x88,0x80,0x19,0x80,0x28,0x80,0xE3,0x80,0x11}; // {0x80,0x40,0xC0,byte1,0xC0,byte2,0xC0,byte3,0xC0,byte4,0xC0,byte5,0xC0,byte6}; const uint8_t lcd_init_clr_b14[] = {0x80,0x40,0xC0,0,0xC0,0,0xC0,0,0xC0,0,0xC0,0,0xC0,0,0xC0,0,0xC0,0}; -const uint8_t lcd_init_clr_b19[] = {0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00}; -RAM uint8_t display_buff[6]; -RAM uint8_t display_cmp_buff[6]; +/* Test cmd (): + * 0400007ceaa49cacbcf0fcc804ffffffff, + * 0400007c0449 + * 0400007cf3c8 - blink + */ +const uint8_t lcd_init_b19[] = { + 0xea, // Set IC Operation(ICSET): Software Reset, Internal oscillator circuit + 0xa4, // Display control (DISCTL): Normal mode, FRAME flip, Power save mode 1 +// 0x9c, // Address set (ADSET): 0x1C ? + 0xac, // Display control (DISCTL): Power save mode 1, FRAME flip, Power save mode 1 + 0xbc, // Display control (DISCTL): Power save mode 3, FRAME flip, Power save mode 1 + 0xf0, // Blink control (BLKCTL): Off + 0xfc, // All pixel control (APCTL): Normal + 0xc8, // Mode Set (MODE SET): Display ON, 1/3 Bias + 0x00, // Set Address 0 + // Clear 18 bytes RAM BU9792AFUV + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00, + 0x00,0x00 +}; typedef struct __attribute__((packed)) _dma_uart_buf_t { volatile uint32_t dma_len; @@ -50,32 +94,6 @@ static _attribute_ram_code_ uint8_t reverse(uint8_t revByte) { revByte = (revByte & 0xAA) >> 1 | (revByte & 0x55) << 1; return revByte; } -/* -static void lcd_send_i2c_byte(uint8_t cmd) { - if ((reg_clk_en0 & FLD_CLK0_I2C_EN)==0) - init_i2c(); - reg_i2c_id = lcd_i2c_addr; - reg_i2c_adr = cmd; - reg_i2c_ctrl = FLD_I2C_CMD_START | FLD_I2C_CMD_ID | FLD_I2C_CMD_ADDR | FLD_I2C_CMD_STOP; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); -} - -static void lcd_send_i2c_buf(uint8_t * dataBuf, uint32_t dataLen) { - if ((reg_clk_en0 & FLD_CLK0_I2C_EN)==0) - init_i2c(); - uint8_t * p = dataBuf; - reg_i2c_id = lcd_i2c_addr; - reg_i2c_ctrl = FLD_I2C_CMD_START | FLD_I2C_CMD_ID; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - while (dataLen--) { - reg_i2c_do = *p++; - reg_i2c_ctrl = FLD_I2C_CMD_DO; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); - } - reg_i2c_ctrl = FLD_I2C_CMD_STOP; - while (reg_i2c_status & FLD_I2C_CMD_BUSY); -} -*/ // UART 38400 BAUD #define UART_BAUD 38400 @@ -93,7 +111,8 @@ static void lcd_send_i2c_buf(uint8_t * dataBuf, uint32_t dataLen) { #define bwpc 9 #endif -_attribute_ram_code_ void lcd_send_uart(void) { +_attribute_ram_code_ +void lcd_send_uart(void) { // init uart reg_clk_en0 |= FLD_CLK0_UART_EN; ///reg_clk_en1 |= FLD_CLK1_DMA_EN; @@ -126,7 +145,8 @@ _attribute_ram_code_ void lcd_send_uart(void) { } -_attribute_ram_code_ void send_to_lcd(void){ +_attribute_ram_code_ +void send_to_lcd(void){ unsigned int buff_index; uint8_t * p = display_buff; if (lcd_i2c_addr) { @@ -137,7 +157,6 @@ _attribute_ram_code_ void send_to_lcd(void){ gpio_setup_up_down_resistor(I2C_SDA, PM_PIN_PULLUP_10K); } reg_i2c_id = lcd_i2c_addr; - if (lcd_i2c_addr == (B14_I2C_ADDR << 1)) { // B1.4, B1.7, B2.0 reg_i2c_adr_dat = 0x4080; @@ -151,8 +170,8 @@ _attribute_ram_code_ void send_to_lcd(void){ } reg_i2c_ctrl = FLD_I2C_CMD_STOP; } else { // (lcd_i2c_addr == (B19_I2C_ADDR << 1)) - // B1.9 - reg_i2c_adr = 0x04; + // B1.9 BU9792AFUV + reg_i2c_adr = 0x04; // addr: 4 reg_i2c_do = reverse(*p++); reg_i2c_di = reverse(*p++); reg_i2c_ctrl = FLD_I2C_CMD_ID | FLD_I2C_CMD_ADDR | FLD_I2C_CMD_DO | FLD_I2C_CMD_DI | FLD_I2C_CMD_START; @@ -186,6 +205,8 @@ _attribute_ram_code_ void send_to_lcd(void){ } } +//const uint8_t lcd_init_cmd[] = {0xea,0xf0, 0xc0, 0xbc}; // sleep all 9.4 uA + void init_lcd(void){ lcd_i2c_addr = (uint8_t) scan_i2c_addr(B14_I2C_ADDR << 1); if (lcd_i2c_addr) { // B1.4, B1.7, B2.0 @@ -198,16 +219,8 @@ void init_lcd(void){ } lcd_i2c_addr = (uint8_t) scan_i2c_addr(B19_I2C_ADDR << 1); if (lcd_i2c_addr) { // B1.9 - lcd_send_i2c_byte(0xEA); // Set IC Operation(ICSET): Software Reset, Internal oscillator circuit - sleep_us(240); - lcd_send_i2c_byte(0xA4); // Display control (DISCTL): Normal mode, FRAME flip, Power save mode 1 - lcd_send_i2c_byte(0x9C); // ? Address set (ADSET): 0x1C ? - lcd_send_i2c_byte(0xAC); // Display control (DISCTL): Power save mode 1, FRAME flip, Power save mode 1 - lcd_send_i2c_byte(0xBC); // Display control (DISCTL): Power save mode 3, FRAME flip, Power save mode 1 - lcd_send_i2c_byte(0xF0); // Blink control (BLKCTL): Off - lcd_send_i2c_byte(0xFC); // All pixel control (APCTL): Normal - lcd_send_i2c_buf((uint8_t *) lcd_init_clr_b19, sizeof(lcd_init_clr_b19)); - lcd_send_i2c_byte(0xC8); // Mode Set (MODE SET): Display ON, 1/3 Bias + lcd_send_i2c_buf((uint8_t *) lcd_init_b19, sizeof(lcd_init_b19)); + lcd_send_i2c_buf((uint8_t *) lcd_init_b19, sizeof(lcd_init_b19)); return; } // B1.6 (UART), lcd_i2c_addr = 0 @@ -218,12 +231,6 @@ void init_lcd(void){ utxb.end = 0x55; } -_attribute_ram_code_ void update_lcd(){ - if (memcmp(&display_cmp_buff, &display_buff, sizeof(display_buff))) { - send_to_lcd(); - memcpy(&display_cmp_buff, &display_buff, sizeof(display_buff)); - } -} /* 0x00 = " " * 0x20 = "°Г" * 0x40 = " -" @@ -232,10 +239,12 @@ _attribute_ram_code_ void update_lcd(){ * 0xA0 = "°C" * 0xC0 = " =" * 0xE0 = "°E" */ -_attribute_ram_code_ void show_temp_symbol(uint8_t symbol) { +_attribute_ram_code_ +void show_temp_symbol(uint8_t symbol) { display_buff[2] &= ~0xE0; display_buff[2] |= symbol & 0xE0; } + /* 0 = " " off, * 1 = " ^-^ " * 2 = " -^- " @@ -244,19 +253,22 @@ _attribute_ram_code_ void show_temp_symbol(uint8_t symbol) { * 5 = "(^-^)" happy * 6 = "(-^-)" sad * 7 = "(ooo)" */ -_attribute_ram_code_ void show_smiley(uint8_t state){ +_attribute_ram_code_ +void show_smiley(uint8_t state){ display_buff[2] &= ~0x07; display_buff[2] |= state & 0x07; } -_attribute_ram_code_ void show_ble_symbol(bool state){ +_attribute_ram_code_ +void show_ble_symbol(bool state){ if (state) display_buff[2] |= LCD_SYM_BLE; else display_buff[2] &= ~LCD_SYM_BLE; } -_attribute_ram_code_ void show_battery_symbol(bool state){ +_attribute_ram_code_ +void show_battery_symbol(bool state){ if (state) display_buff[1] |= LCD_SYM_BAT; else @@ -264,7 +276,8 @@ _attribute_ram_code_ void show_battery_symbol(bool state){ } /* number in 0.1 (-995..19995), Show: -99 .. -9.9 .. 199.9 .. 1999 */ -_attribute_ram_code_ __attribute__((optimize("-Os"))) void show_big_number_x10(int16_t number){ +_attribute_ram_code_ +__attribute__((optimize("-Os"))) void show_big_number_x10(int16_t number){ // display_buff[4] = point?0x08:0x00; if (number > 19995) { display_buff[3] = 0; @@ -301,7 +314,8 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) void show_big_number_x10(i } /* -9 .. 99 */ -_attribute_ram_code_ __attribute__((optimize("-Os"))) void show_small_number(int16_t number, bool percent){ +_attribute_ram_code_ +__attribute__((optimize("-Os"))) void show_small_number(int16_t number, bool percent){ display_buff[1] = display_buff[1] & 0x08; // and battery display_buff[0] = percent?0x08:0x00; if (number > 99) { @@ -321,7 +335,8 @@ _attribute_ram_code_ __attribute__((optimize("-Os"))) void show_small_number(int } #if USE_CLOCK -_attribute_ram_code_ void show_clock(void) { +_attribute_ram_code_ +void show_clock(void) { uint32_t tmp = utc_time_sec / 60; uint32_t min = tmp % 60; uint32_t hrs = tmp / 60 % 24; diff --git a/src/lcd_mjwsd05mmc.c b/src/lcd_mjwsd05mmc.c index 42b559cf..050d4e66 100644 --- a/src/lcd_mjwsd05mmc.c +++ b/src/lcd_mjwsd05mmc.c @@ -17,6 +17,7 @@ #define lcd_send_i2c_buf(b, a) send_i2c_buf(lcd_i2c_addr, (uint8_t *) b, a) RAM uint8_t lcd_i2c_addr; +RAM lcd_flg_t lcd_flg; RAM uint8_t display_buff[LCD_BUF_SIZE]; RAM uint8_t display_cmp_buff[LCD_BUF_SIZE]; @@ -166,7 +167,15 @@ const uint8_t sb_s4[4][DEF_MJWSD05MMC_SUMBOL_SIGMENTS*2] = { 3. 0xf0 - Blink control (BLKCTL): Off 4. 0xfc - All pixel control (APCTL): Normal */ -const uint8_t lcd_init_cmd[] = {0xea,0xbe,0xf0,0xfc}; +//const uint8_t lcd_init_cmd[] = {0xea,0xbe,0xf0,0xfc}; +/* LCD controller initialize +1. 0xea - Set IC Operation(ICSET): Software Reset, Internal oscillator circuit +2. 0xf0 - Blink control (BLKCTL): Off +4. 0xc0 - Mode Set (MODE SET): Display ON ? +2. 0xbc - Display control (DISCTL): Power save mode 3, FRAME flip, Power save mode 1 +*/ +const uint8_t lcd_init1_cmd[] = {0xea,0xf0, 0xc0, 0xbc}; + const uint8_t lcd_init_clr_b19[] = {0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00}; // runtime: 600 us if I2C 450 kHz @@ -196,13 +205,14 @@ _attribute_ram_code_ void send_to_lcd(void){ } } -/* LCD controller initialize -1. 0xea - Set IC Operation(ICSET): Software Reset, Internal oscillator circuit -2. 0xf0 - Blink control (BLKCTL): Off -4. 0xc0 - Mode Set (MODE SET): Display ON ? -2. 0xbc - Display control (DISCTL): Power save mode 3, FRAME flip, Power save mode 1 -*/ -const uint8_t lcd_init1_cmd[] = {0xea,0xf0, 0xc0, 0xbc}; +_attribute_ram_code_ +void update_lcd(void){ + if (memcmp(&display_cmp_buff, &display_buff, sizeof(display_buff))) { + send_to_lcd(); + memcpy(&display_cmp_buff, &display_buff, sizeof(display_buff)); + lcd_flg.b.send_notify = lcd_flg.b.notify_on; // set flag LCD for send notify + } +} void init_lcd(void){ lcd_i2c_addr = (uint8_t) scan_i2c_addr(MJWSD05MMC_LCD_I2C_ADDR << 1); @@ -227,13 +237,6 @@ void init_lcd(void){ } } -_attribute_ram_code_ void update_lcd(void){ - if (memcmp(&display_cmp_buff, &display_buff, sizeof(display_buff))) { - send_to_lcd(); - memcpy(&display_cmp_buff, &display_buff, sizeof(display_buff)); - } -} - _attribute_ram_code_ __attribute__((optimize("-Os"))) static void lcd_set_digit(uint8_t *buf, uint8_t digit, const uint8_t *segments) { // set the segments, there are up to 11 segments in a digit int segment_byte; @@ -763,7 +766,7 @@ void show_low_bat(void) { display_buff[2] |= BIT(1) | BIT(3) | BIT(7); // "bat" display_buff[17] |= BIT(4); - //show_s1_number_x100(measured_data.battery_mv * 10, 0); + //show_s1_number_x100(measured_data.average_battery_mv * 10, 0); send_to_lcd(); } @@ -796,13 +799,12 @@ _attribute_ram_code_ __attribute__((optimize("-O2"))) void lcd(void) { uint8_t screen_type = cfg.flg2.screen_type; - if(chow_tick_sec >= utc_time_sec) + if(lcd_flg.chow_ext_ut >= utc_time_sec) screen_type = SCR_TYPE_EXT; -// else chow_tick_sec = 0; show_ble_symbol(ble_connected || (rest_adv_int_tad & 2)); - show_battery_symbol(measured_data.battery_mv < 2400); + show_battery_symbol(measured_data.average_battery_mv < 2400); switch(screen_type) { case SCR_TYPE_TEMP: if (cfg.flg.temp_F_or_C) { @@ -840,7 +842,7 @@ void lcd(void) { show_s4_number_x10(measured_data.humi_x01, LCD_SYM_P); break; case SCR_TYPE_BAT_V: - show_s1_number_x100((measured_data.battery_mv / 10), 0); + show_s1_number_x100((measured_data.average_battery_mv / 10), 0); show_battery_symbol(1); if (cfg.flg.temp_F_or_C) show_s3_number_x10((((measured_data.temp / 5) * 9) + 3200) / 10, LCD_SYM_F); // convert C to F diff --git a/src/logger.c b/src/logger.c index 891be6cd..eddab1b6 100644 --- a/src/logger.c +++ b/src/logger.c @@ -161,11 +161,11 @@ void write_memo(void) { if (cfg.averaging_measurements == 1) { mblk.temp = measured_data.temp; mblk.humi = measured_data.humi; - mblk.vbat = measured_data.battery_mv; + mblk.vbat = measured_data.average_battery_mv; } else { summ_data.temp += measured_data.temp; summ_data.humi += measured_data.humi; - summ_data.battery_mv += measured_data.battery_mv; + summ_data.battery_mv += measured_data.average_battery_mv; summ_data.count++; if (cfg.averaging_measurements > summ_data.count) return; diff --git a/src/mi_beacon.c b/src/mi_beacon.c index c1f2a77e..8f29ae4b 100644 --- a/src/mi_beacon.c +++ b/src/mi_beacon.c @@ -41,6 +41,7 @@ typedef struct _mi_beacon_data_t { // out data int16_t temp; // x0.1 C uint16_t humi; // x0.1 % uint8_t batt; // 0..100 % + uint8_t stage; } mi_beacon_data_t; RAM mi_beacon_data_t mi_beacon_data; @@ -61,21 +62,22 @@ void mi_beacon_init(void) { /* Averaging measurements */ _attribute_ram_code_ void mi_beacon_summ(void) { + if(mib_summ_data.count > 0x7fff) { + memset(&mib_summ_data, 0, sizeof(mib_summ_data)); + } mib_summ_data.temp += measured_data.temp; mib_summ_data.humi += measured_data.humi; - mib_summ_data.batt += measured_data.battery_mv; + mib_summ_data.batt += measured_data.average_battery_mv; mib_summ_data.count++; } -RAM uint8_t adv_mi_crypt_num; /* Create encrypted mi beacon packet */ __attribute__((optimize("-Os"))) void mi_encrypt_data_beacon(void) { beacon_nonce.cnt32 = adv_buf.send_count; adv_buf.update_count = -1; // next call if next measured - adv_mi_crypt_num++; - if (adv_mi_crypt_num > 2) { - adv_mi_crypt_num = 0; + if (++mi_beacon_data.stage > 2) { + mi_beacon_data.stage = 0; if(mib_summ_data.count) { mi_beacon_data.temp = ((int16_t)(mib_summ_data.temp/(int32_t)mib_summ_data.count) + 5)/10; mi_beacon_data.humi = ((uint16_t)(mib_summ_data.humi/mib_summ_data.count) + 5)/10; @@ -94,7 +96,7 @@ void mi_encrypt_data_beacon(void) { p->head.counter = beacon_nonce.cnt; adv_mi_data_t data; memcpy(p->MAC, mac_public, 6); - switch (adv_mi_crypt_num) { + switch (mi_beacon_data.stage) { case 0: data.id = XIAOMI_DATA_ID_Temperature; // XIAOMI_DATA_ID data.size = 2; @@ -153,6 +155,7 @@ void mi_encrypt_data_beacon(void) { pmic, 4); // указатель куда писать типа подпись-"контрольную сумму" шифра } #if USE_WK_RDS_COUNTER +/* n - RDS_TYPES */ void mi_encrypt_event_beacon(uint8_t n) { padv_mi_cr_ev1_t p = (padv_mi_cr_ev1_t)&adv_buf.data; uint8_t * pmic; diff --git a/src/project.mk b/src/project.mk index 132644b1..6d2ef670 100644 --- a/src/project.mk +++ b/src/project.mk @@ -4,6 +4,7 @@ OUT_DIR += /src OBJS += \ $(OUT_PATH)/src/utils.o \ $(OUT_PATH)/src/app.o \ +$(OUT_PATH)/src/lcd.o \ $(OUT_PATH)/src/lcd_lywsd03mmc.o \ $(OUT_PATH)/src/lcd_cgdk2.o \ $(OUT_PATH)/src/lcd_mjwsd05mmc.o \