Skip to content

Commit

Permalink
Set RTC after upload on Teensy 4 and 4.1, thanks to @mecparts
Browse files Browse the repository at this point in the history
  • Loading branch information
Koromix committed Jan 18, 2021
1 parent 6449e1f commit 103a1dc
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 3 deletions.
44 changes: 43 additions & 1 deletion src/libty/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#ifndef _WIN32
#include <sys/stat.h>
#endif
#include <time.h>
#include "../libhs/device.h"
#include "board_priv.h"
#include "class_priv.h"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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");
Expand Down
5 changes: 4 additions & 1 deletion src/libty/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/libty/class_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
36 changes: 35 additions & 1 deletion src/libty/class_teensy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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,
Expand All @@ -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
};

0 comments on commit 103a1dc

Please sign in to comment.