diff --git a/src/libty/board.c b/src/libty/board.c index cebfbc6d..9984930e 100644 --- a/src/libty/board.c +++ b/src/libty/board.c @@ -12,6 +12,7 @@ #ifndef _WIN32 #include #endif +#include #include "../libhs/device.h" #include "board_priv.h" #include "class_priv.h" @@ -419,6 +420,25 @@ int ty_board_reboot(ty_board *board) return r; } +int ty_board_set_rtc(ty_board *board, int64_t time) +{ + assert(board); + + ty_board_interface *iface; + int r; + + r = ty_board_open_interface(board, TY_BOARD_CAPABILITY_RTC, &iface); + if (r < 0) + return r; + if (!r) + return ty_error(TY_ERROR_MODE, "Cannot set RTC on board '%s'", board->tag); + + r = (*iface->class_vtable->set_rtc)(iface, time); + + ty_board_interface_close(iface); + return r; +} + ty_board_interface *ty_board_interface_ref(ty_board_interface *iface) { assert(iface); @@ -651,7 +671,7 @@ static int run_upload(ty_task *task) wait: r = ty_board_wait_for(board, TY_BOARD_CAPABILITY_UPLOAD, - flags & TY_UPLOAD_WAIT ? -1 : MANUAL_REBOOT_DELAY); + flags & TY_UPLOAD_WAIT ? -1 : MANUAL_REBOOT_DELAY); if (r < 0) return r; if (!r) { @@ -673,6 +693,28 @@ static int run_upload(ty_task *task) return r; } + if (ty_board_has_capability(board, TY_BOARD_CAPABILITY_RTC) && !(flags & TY_UPLOAD_NORTC)) { +#ifdef _WIN32 + __time64_t now; + struct tm ti; + + _time64(&now); + _localtime64_s(&ti, &now); + now += ti.tm_gmtoff; +#else + time_t now; + struct tm ti; + + now = time(NULL); + localtime_r(&now, &ti); + now += ti.tm_gmtoff; +#endif + + r = ty_board_set_rtc(board, (int64_t)now); + if (r < 0) + return r; + } + if (!(flags & TY_UPLOAD_NORESET)) { if (flags & TY_UPLOAD_DELEGATE) { ty_log(TY_LOG_INFO, "Waiting for Teensy Loader"); diff --git a/src/libty/board.h b/src/libty/board.h index 153eacec..a65f3d1a 100644 --- a/src/libty/board.h +++ b/src/libty/board.h @@ -33,6 +33,7 @@ typedef enum ty_board_capability { TY_BOARD_CAPABILITY_UPLOAD, TY_BOARD_CAPABILITY_RESET, TY_BOARD_CAPABILITY_REBOOT, + TY_BOARD_CAPABILITY_RTC, TY_BOARD_CAPABILITY_SERIAL, TY_BOARD_CAPABILITY_COUNT @@ -48,7 +49,8 @@ enum { TY_UPLOAD_WAIT = 1, TY_UPLOAD_NORESET = 2, TY_UPLOAD_NOCHECK = 4, - TY_UPLOAD_DELEGATE = 8 + TY_UPLOAD_NORTC = 8, + TY_UPLOAD_DELEGATE = 16 }; #define TY_UPLOAD_MAX_FIRMWARES 256 @@ -97,6 +99,7 @@ ssize_t ty_board_serial_write(ty_board *board, const char *buf, size_t size); int ty_board_upload(ty_board *board, struct ty_firmware *fw, ty_board_upload_progress_func *pf, void *udata); int ty_board_reset(ty_board *board); int ty_board_reboot(ty_board *board); +int ty_board_set_rtc(ty_board *board, int64_t time); ty_board_interface *ty_board_interface_ref(ty_board_interface *iface); void ty_board_interface_unref(ty_board_interface *iface); diff --git a/src/libty/class_priv.h b/src/libty/class_priv.h index 65d7ad9f..496e7548 100644 --- a/src/libty/class_priv.h +++ b/src/libty/class_priv.h @@ -32,6 +32,7 @@ struct _ty_class_vtable { ty_board_upload_progress_func *pf, void *udata); int (*reset)(ty_board_interface *iface); int (*reboot)(ty_board_interface *iface); + int (*set_rtc)(ty_board_interface *iface, int64_t time); }; struct _ty_class { diff --git a/src/libty/class_teensy.c b/src/libty/class_teensy.c index ffe24e2e..15d3e6a2 100644 --- a/src/libty/class_teensy.c +++ b/src/libty/class_teensy.c @@ -131,6 +131,8 @@ static int teensy_load_interface(ty_board_interface *iface) iface->capabilities |= 1 << TY_BOARD_CAPABILITY_UPLOAD; iface->capabilities |= 1 << TY_BOARD_CAPABILITY_RESET; } + if (iface->model == TY_MODEL_TEENSY_40 || iface->model == TY_MODEL_TEENSY_41) + iface->capabilities |= 1 << TY_BOARD_CAPABILITY_RTC; } break; case TEENSY_USAGE_PAGE_RAWHID: { @@ -787,6 +789,37 @@ static int teensy_reboot(ty_board_interface *iface) return r; } +static int teensy_set_rtc(ty_board_interface *iface, int64_t time) +{ + unsigned int halfkay_version; + size_t min_address, max_address, block_size; + + int r = get_halfkay_settings(iface->model, &halfkay_version, &min_address, &max_address, &block_size); + if (r < 0) + return r; + + uint8_t buf[12]; + { + unsigned long hi = (unsigned long)(time >> 17); + unsigned long lo = (unsigned long)(time << 15); + + buf[0] = 0xB7; + buf[1] = 0x31; + buf[2] = 0xC2; + buf[3] = 0x89; + buf[4] = lo & 0xFF; + buf[5] = (lo >> 8) & 0xFF; + buf[6] = (lo >> 16) & 0xFF; + buf[7] = (lo >> 24) & 0xFF; + buf[8] = hi & 0xFF; + buf[9] = (hi >> 8) & 0xFF; + buf[10] = (hi >> 16) & 0xFF; + buf[11] = (hi >> 24) & 0xFF; + } + + return halfkay_send(iface->port, halfkay_version, block_size, 0xFFFFFF, buf, sizeof(buf), 25); +} + const struct _ty_class_vtable _ty_teensy_class_vtable = { .load_interface = teensy_load_interface, .update_board = teensy_update_board, @@ -798,5 +831,6 @@ const struct _ty_class_vtable _ty_teensy_class_vtable = { .serial_write = teensy_serial_write, .upload = teensy_upload, .reset = teensy_reset, - .reboot = teensy_reboot + .reboot = teensy_reboot, + .set_rtc = teensy_set_rtc };