diff --git a/src/user_custs1_impl.c b/src/user_custs1_impl.c index fd30e0e..eac6f14 100644 --- a/src/user_custs1_impl.c +++ b/src/user_custs1_impl.c @@ -114,6 +114,8 @@ static int jieqi_info[] = int year=2025, month=0, date=0, wday=3; int l_year=4, l_month=11, l_date=1; int hour=0, minute=0, second=0; +// 上次对时后,经过的分钟数 +int cal_minute=-1; static int get_lunar_mdays(int mon, int *yinfo_out) @@ -252,6 +254,9 @@ int clock_update(int inc) if((minute%10)==0) retv = 2; + if(cal_minute>=0) + cal_minute += 1; + if(minute>=60){ minute = 0; hour += 1; @@ -282,17 +287,20 @@ void clock_set(uint8_t *buf) l_date = buf[11]-1; get_holiday(); + + cal_minute = 0; + + app_clock_timer_restart(); } void clock_push(void) { - uint8_t buf[8]; - struct custs1_val_set_req *req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_SET_REQ, prf_get_task_from_id(TASK_ID_CUSTS1), TASK_APP, custs1_val_set_req, 8); + struct custs1_val_set_req *req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_SET_REQ, prf_get_task_from_id(TASK_ID_CUSTS1), TASK_APP, custs1_val_set_req, 11); req->conidx = app_env->conidx; req->handle = SVC1_IDX_LONG_VALUE_VAL; - req->length = 8; + req->length = 11; req->value[0] = year&0xff; req->value[1] = year>>8; req->value[2] = month; @@ -300,7 +308,10 @@ void clock_push(void) req->value[4] = hour; req->value[5] = minute; req->value[6] = second; - req->value[7] = 0; + req->value[7] = (cal_minute&0xff); + req->value[8] = (cal_minute>>8 )&0xff; + req->value[9] = (cal_minute>>16)&0xff; + req->value[10]= (cal_minute>>24)&0xff; KE_MSG_SEND(req); } @@ -632,6 +643,14 @@ void user_svc1_long_val_wr_ind_handler(ke_msg_id_t const msgid, struct custs1_va clock_set((uint8_t*)param->value); clock_draw(DRAW_BT|UPDATE_FAST); clock_print(); + }else if(param->value[0]==0x92){ + int diff_sec; + diff_sec = param->value[1]; + diff_sec |= param->value[2]<<8; + diff_sec = (diff_sec<<16)>>16; + printk("Calibration: %02x\n", diff_sec); + clock_fixup_set(diff_sec, cal_minute); + cal_minute = 0; }else if(param->value[0]>=0xa0){ ota_handle((u8*)param->value); } diff --git a/src/user_peripheral.c b/src/user_peripheral.c index a541bca..42d4136 100644 --- a/src/user_peripheral.c +++ b/src/user_peripheral.c @@ -66,7 +66,7 @@ **************************************************************************************** */ -uint8_t app_connection_idx __SECTION_ZERO("retention_mem_area0"); +int app_connection_idx __SECTION_ZERO("retention_mem_area0"); timer_hnd app_clock_timer_used __SECTION_ZERO("retention_mem_area0"); //@RETENTION MEMORY timer_hnd app_param_update_request_timer_used __SECTION_ZERO("retention_mem_area0"); @@ -76,6 +76,8 @@ static int otp_boot; static char adv_name[20]; char *bt_id = adv_name+12; int clock_interval; +int clock_fixup_value; +int clock_fixup_count; const volatile u32 epd_version[3] = {0xF9A51379, ~0xF9A51379, EPD_VERSION}; @@ -180,6 +182,9 @@ void user_app_init(void) app_clock_timer_used = EASY_TIMER_INVALID_TIMER; clock_interval = 60; // 60s + clock_fixup_value = 0; + clock_fixup_count = 0; + adv_state = 0; fspi_config(0x00030605); @@ -192,17 +197,48 @@ void user_app_init(void) } + app_connection_idx = -1; default_app_on_init(); } +// 时钟快慢修正 +// minutes : 自上次对时后,经过的分钟数 +// diff_sec: 自上次对时后,误差的秒数 +// 误差为正数,说明时钟快了。将定时器加上一个修正值,让它慢一点。 +// 误差为负数,说明时钟慢了。将定时器减去一个修正值,让它快一点。 +void clock_fixup_set(int diff_sec, int minutes) +{ + int new_fixup_value = diff_sec*100*4096/minutes; + clock_fixup_value += new_fixup_value; +} + + +static int clock_fixup(void) +{ + int value; + + clock_fixup_count += clock_fixup_value; + + value = clock_fixup_count>>12; + clock_fixup_count &= 0xfff; + + return value; +} + + static void app_clock_timer_cb(void) { - app_clock_timer_used = app_easy_timer(clock_interval*100, app_clock_timer_cb); + int adj = clock_fixup(); + app_clock_timer_used = app_easy_timer(clock_interval*100+adj, app_clock_timer_cb); int stat = clock_update(clock_interval); clock_print(); + if(app_connection_idx!=-1){ + clock_push(); + } + int flags = UPDATE_FLY; if(stat>=3){ flags = DRAW_BT | UPDATE_FULL; @@ -224,6 +260,13 @@ static void app_clock_timer_cb(void) } +void app_clock_timer_restart(void) +{ + app_easy_timer_cancel(app_clock_timer_used); + app_clock_timer_used = app_easy_timer(clock_interval*100, app_clock_timer_cb); +} + + void user_app_on_db_init_complete( void ) { printk("\nuser_app_on_db_init_complete!\n"); @@ -317,6 +360,7 @@ void user_app_disconnect(struct gapc_disconnect_ind const *param) app_param_update_request_timer_used = EASY_TIMER_INVALID_TIMER; } + app_connection_idx = -1; adv_state = 0; if(param->reason!=CO_ERROR_REMOTE_USER_TERM_CON){ diff --git a/src/user_peripheral.h b/src/user_peripheral.h index 9e2e95c..b619703 100644 --- a/src/user_peripheral.h +++ b/src/user_peripheral.h @@ -98,6 +98,9 @@ void user_app_on_db_init_complete( void ); void user_app_before_sleep(void); +void app_clock_timer_restart(void); + +void clock_fixup_set(int diff_sec, int minutes); /** **************************************************************************************** diff --git a/weble/weble.html b/weble/weble.html index 377ae75..269fe20 100644 --- a/weble/weble.html +++ b/weble/weble.html @@ -9,6 +9,7 @@ +
@@ -90,6 +91,7 @@ connected = true; document.getElementById('setime-button').disabled = false; document.getElementById('upfirm-button').disabled = false; + document.getElementById('calibration-button').disabled = false; document.getElementById('connect-button').textContent = "断开"; } catch (error) { console.log('连接失败:', error); @@ -103,6 +105,13 @@ async function onSetTime() { document.getElementById('setime-button').disabled = true; + // 等待整秒时间 + while(true){ + const tm_ms = Date.now(); + if((tm_ms%1000)==0) + break; + } + var today = new Date(); year = today.getFullYear(); month = today.getMonth(); @@ -266,6 +275,65 @@ } +/////////////////////////////////////////////////////////////////////////////////////////////////// + + + async function onCalibration() { + document.getElementById('calibration-button').disabled = true; + + var minute, second, last_minute, cal_minute; + + cur_time = await longValue.readValue(); + last_minute = cur_time.getUint8(5); + cal_minute = cur_time.getInt32(7, true); + console.log('对时后'+cal_minute+'分钟'); + if(cal_minute==-1){ + console.log('请先对时!'); + }else if(cal_minute<2880){ + console.log('对时与校准间隔太短(小于两天)!'); + }else{ + console.log('等待分钟跳变......'); + while(true) { + cur_time = await longValue.readValue(); + minute = cur_time.getUint8(5); + if(minute != last_minute) + break; + last_minute = minute; + } + second = cur_time.getUint8(6); + + var today = new Date(); + var sys_minute = today.getMinutes(); + var sys_second = today.getSeconds(); + + console.log('设备时间: '+minute+'分'+second+'秒'); + console.log('系统时间: '+sys_minute+'分'+sys_second+'秒'); + + if(minute>sys_minute){ + if(minute-sys_minute>50) + sys_minute += 60; + }else{ + if(sys_minute-minute>50) + minute += 60; + } + + var diff = (minute*60+second)-(sys_minute*60+sys_second); + console.log('时间差: '+diff+'秒'); + + var buf = new Uint8Array(4); + buf[0] = 0x92; + buf[1] = diff%256; + buf[2] = diff/256; + buf[3] = 0x00; + await longValue.writeValue(buf); + + console.log('校准完成'); + } + + document.getElementById('calibration-button').disabled = false; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////// @@ -284,12 +352,14 @@ console.log('设备已断开连接'); connected = false; document.getElementById('setime-button').disabled = true; + document.getElementById('calibration-button').disabled = true; document.getElementById('connect-button').textContent = "连接"; } document.getElementById('connect-button').addEventListener('click', onClick); document.getElementById('setime-button').addEventListener('click', onSetTime); document.getElementById('upfirm-button').addEventListener('click', onUpdate); + document.getElementById('calibration-button').addEventListener('click', onCalibration);