mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge pull request #3107 from kormax/hf-field-timeout
Add 'hf.field.timeout' to prefs
This commit is contained in:
+31
-1
@@ -91,10 +91,12 @@
|
||||
int g_dbglevel = DBG_ERROR;
|
||||
uint8_t g_trigger = 0;
|
||||
bool g_hf_field_active = false;
|
||||
bool g_hf_field_timeout_active = false;
|
||||
extern uint32_t _stack_start[], _stack_end[];
|
||||
common_area_t g_common_area __attribute__((section(".commonarea")));
|
||||
static int button_status = BUTTON_NO_CLICK;
|
||||
static bool allow_send_wtx = false;
|
||||
static uint32_t g_hf_field_activity_timeout_ms = 0;
|
||||
uint16_t g_tearoff_delay_us = 0;
|
||||
bool g_tearoff_enabled = false;
|
||||
uint8_t g_tearoff_skip = 0;
|
||||
@@ -125,6 +127,7 @@ void hf_field_off(void) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
g_hf_field_active = false;
|
||||
g_hf_field_timeout_active = false;
|
||||
}
|
||||
|
||||
void send_wtx(uint16_t wtx) {
|
||||
@@ -1002,6 +1005,17 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
reply_ng(CMD_SET_TEAROFF, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
case CMD_SET_HF_FIELD_TIMEOUT: {
|
||||
if (packet->length != sizeof(uint32_t)) {
|
||||
reply_ng(CMD_SET_HF_FIELD_TIMEOUT, PM3_EINVARG, NULL, 0);
|
||||
break;
|
||||
}
|
||||
uint32_t timeout_ms = 0;
|
||||
memcpy(&timeout_ms, packet->data.asBytes, sizeof(timeout_ms));
|
||||
g_hf_field_activity_timeout_ms = timeout_ms;
|
||||
reply_ng(CMD_SET_HF_FIELD_TIMEOUT, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
// always available
|
||||
case CMD_HF_DROPFIELD: {
|
||||
hf_field_off();
|
||||
@@ -2699,6 +2713,8 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
}
|
||||
case CMD_FPGA_MAJOR_MODE_OFF: { // ## FPGA Control
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
g_hf_field_active = false;
|
||||
g_hf_field_timeout_active = false;
|
||||
SpinDelay(200);
|
||||
LED_D_OFF(); // LED D indicates field ON or OFF
|
||||
break;
|
||||
@@ -3315,6 +3331,8 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
StartTickCount();
|
||||
uint32_t last_activity_tick = GetTickCount();
|
||||
uint32_t last_activity_label = GetTickCountLabel();
|
||||
|
||||
#ifdef WITH_LCD
|
||||
LCDInit();
|
||||
@@ -3378,12 +3396,24 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||
int ret = receive_ng(&rx);
|
||||
if (ret == PM3_SUCCESS) {
|
||||
PacketReceived(&rx);
|
||||
last_activity_label = GetTickCountLabel();
|
||||
last_activity_tick = GetTickCount();
|
||||
} else if (ret != PM3_ENODATA) {
|
||||
|
||||
Dbprintf("Error in frame reception: %d %s", ret, (ret == PM3_EIO) ? "PM3_EIO" : "");
|
||||
// TODO if error, shall we resync ?
|
||||
}
|
||||
|
||||
if (g_hf_field_activity_timeout_ms > 0 && g_hf_field_timeout_active) {
|
||||
uint32_t tickcount_label = GetTickCountLabel();
|
||||
if (tickcount_label != last_activity_label) {
|
||||
last_activity_label = tickcount_label;
|
||||
last_activity_tick = GetTickCount();
|
||||
} else if (GetTickCountDelta(last_activity_tick) >= g_hf_field_activity_timeout_ms) {
|
||||
hf_field_off();
|
||||
Dbprintf("HF field auto-off: inactivity timeout (%u ms). To disable, use 'prefs set hf.field.timeout_sec --sec 0'", g_hf_field_activity_timeout_ms);
|
||||
}
|
||||
}
|
||||
|
||||
// Press button for one second to enter a possible standalone mode
|
||||
button_status = BUTTON_HELD(1000);
|
||||
if (button_status == BUTTON_HOLD) {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
extern uint8_t g_trigger;
|
||||
extern bool g_hf_field_active;
|
||||
extern bool g_hf_field_timeout_active;
|
||||
void hf_field_off(void);
|
||||
int tearoff_hook(void);
|
||||
|
||||
|
||||
@@ -562,12 +562,38 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v) {
|
||||
AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data
|
||||
while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF)) {}; // wait till transfer is complete
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Write the FPGA setup word (that determines what mode the logic is in, read
|
||||
// vs. clone vs. etc.). This is now a special case of FpgaSendCommand() to
|
||||
// avoid changing this function's occurrence everywhere in the source code.
|
||||
//-----------------------------------------------------------------------------
|
||||
void FpgaWriteConfWord(uint16_t v) {
|
||||
const int current = FpgaGetCurrent();
|
||||
|
||||
// Keep track of whether or not we should be monitoring the HF field timeout
|
||||
if (current == FPGA_BITSTREAM_HF || current == FPGA_BITSTREAM_HF_15 || current == FPGA_BITSTREAM_HF_FELICA) {
|
||||
const uint16_t major = v & FPGA_MAJOR_MODE_MASK;
|
||||
const uint16_t minor = v & FPGA_MINOR_MODE_MASK;
|
||||
|
||||
switch (major) {
|
||||
case FPGA_MAJOR_MODE_HF_READER:
|
||||
g_hf_field_timeout_active = true;
|
||||
break;
|
||||
case FPGA_MAJOR_MODE_HF_ISO14443A:
|
||||
g_hf_field_timeout_active = (minor == FPGA_HF_ISO14443A_READER_LISTEN || minor == FPGA_HF_ISO14443A_READER_MOD);
|
||||
break;
|
||||
case FPGA_MAJOR_MODE_HF_ISO18092:
|
||||
g_hf_field_timeout_active = (minor & FPGA_HF_ISO18092_FLAG_READER) != 0;
|
||||
break;
|
||||
default:
|
||||
g_hf_field_timeout_active = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
g_hf_field_timeout_active = false;
|
||||
}
|
||||
|
||||
FpgaSendCommand(FPGA_CMD_SET_CONFREG, v);
|
||||
}
|
||||
|
||||
|
||||
+14
-2
@@ -212,14 +212,26 @@ void CmdsHelp(const command_t Commands[]) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
||||
int i = 0;
|
||||
size_t max_name_len = 16; // minimum width for command name column
|
||||
while (Commands[i].Name) {
|
||||
if (Commands[i].IsAvailable()) {
|
||||
size_t name_len = strlen(Commands[i].Name);
|
||||
if (name_len > max_name_len) {
|
||||
max_name_len = name_len;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (Commands[i].Name) {
|
||||
if (Commands[i].IsAvailable()) {
|
||||
uint8_t old_printAndLog = g_printAndLog;
|
||||
g_printAndLog &= PRINTANDLOG_PRINT;
|
||||
if (Commands[i].Name[0] == '-' || Commands[i].Name[0] == ' ') {
|
||||
PrintAndLogEx(NORMAL, "%-16s %s", Commands[i].Name, Commands[i].Help);
|
||||
PrintAndLogEx(NORMAL, "%-*s %s", (int)max_name_len, Commands[i].Name, Commands[i].Help);
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, _GREEN_("%-16s")" %s", Commands[i].Name, Commands[i].Help);
|
||||
PrintAndLogEx(NORMAL, _GREEN_("%-*s") " %s", (int)max_name_len, Commands[i].Name, Commands[i].Help);
|
||||
}
|
||||
g_printAndLog = old_printAndLog;
|
||||
}
|
||||
|
||||
@@ -846,6 +846,30 @@ bool OpenProxmark(pm3_device_t **dev, const char *port, bool wait_for_port, int
|
||||
}
|
||||
}
|
||||
|
||||
int SetHfFieldTimeout(uint32_t timeout_sec, bool quiet) {
|
||||
if (g_session.pm3_present == false) {
|
||||
return PM3_ENOTTY;
|
||||
}
|
||||
|
||||
uint32_t timeout_ms = timeout_sec * 1000U;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_SET_HF_FIELD_TIMEOUT, (uint8_t *)&timeout_ms, sizeof(timeout_ms));
|
||||
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeoutW(CMD_SET_HF_FIELD_TIMEOUT, &resp, 1000, false) == false) {
|
||||
if (!quiet) {
|
||||
PrintAndLogEx(WARNING, "timeout while setting HF field timeout");
|
||||
}
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (resp.status != PM3_SUCCESS && !quiet) {
|
||||
PrintAndLogEx(WARNING, "HF field timeout command failed (%d)", resp.status);
|
||||
}
|
||||
return resp.status;
|
||||
}
|
||||
|
||||
// check if we can communicate with Pm3
|
||||
int TestProxmark(pm3_device_t *dev) {
|
||||
|
||||
@@ -921,6 +945,13 @@ int TestProxmark(pm3_device_t *dev) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if (g_session.hf_field_timeout_sec > 0) {
|
||||
int timeout_res = SetHfFieldTimeout(g_session.hf_field_timeout_sec, true);
|
||||
if (timeout_res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Failed to apply HF field timeout (" _YELLOW_("%u") " s)", g_session.hf_field_timeout_sec);
|
||||
}
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,8 @@ bool WaitForResponseTimeoutW(uint32_t cmd, PacketResponseNG *response, size_t ms
|
||||
bool WaitForResponseTimeout(uint32_t cmd, PacketResponseNG *response, size_t ms_timeout);
|
||||
bool WaitForResponse(uint32_t cmd, PacketResponseNG *response);
|
||||
|
||||
int SetHfFieldTimeout(uint32_t timeout_sec, bool quiet);
|
||||
|
||||
//bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, PacketResponseNG *response, size_t ms_timeout, bool show_warning);
|
||||
bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint32_t start_index, uint8_t *data, uint32_t datalen, PacketResponseNG *response, size_t ms_timeout, bool show_warning);
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ const static vocabulary_t vocabulary[] = {
|
||||
{ 1, "prefs get client.debug" },
|
||||
{ 1, "prefs get client.delay" },
|
||||
{ 1, "prefs get client.timeout" },
|
||||
{ 1, "prefs get hf.field.timeout_sec" },
|
||||
{ 1, "prefs get color" },
|
||||
{ 1, "prefs get savepaths" },
|
||||
{ 1, "prefs get emoji" },
|
||||
@@ -57,6 +58,7 @@ const static vocabulary_t vocabulary[] = {
|
||||
{ 1, "prefs set client.debug" },
|
||||
{ 1, "prefs set client.delay" },
|
||||
{ 1, "prefs set client.timeout" },
|
||||
{ 1, "prefs set hf.field.timeout_sec" },
|
||||
{ 1, "prefs set color" },
|
||||
{ 1, "prefs set emoji" },
|
||||
{ 1, "prefs set hints" },
|
||||
|
||||
@@ -102,6 +102,7 @@ int preferences_load(void) {
|
||||
g_session.client_debug_level = cdbOFF;
|
||||
// g_session.device_debug_level = ddbOFF;
|
||||
g_session.timeout = uart_get_timeouts();
|
||||
g_session.hf_field_timeout_sec = 0;
|
||||
|
||||
g_session.window_changed = false;
|
||||
g_session.plot.x = 10;
|
||||
@@ -329,6 +330,7 @@ void preferences_save_callback(json_t *root) {
|
||||
*/
|
||||
JsonSaveInt(root, "client.exe.delay", g_session.client_exe_delay);
|
||||
JsonSaveInt(root, "client.timeout", g_session.timeout);
|
||||
JsonSaveInt(root, "hf.field.timeout_sec", g_session.hf_field_timeout_sec);
|
||||
|
||||
// MQTT
|
||||
JsonSaveStr(root, "mqtt.server", g_session.mqtt_server);
|
||||
@@ -440,6 +442,10 @@ void preferences_load_callback(json_t *root) {
|
||||
if (json_unpack_ex(root, &up_error, 0, "{s:i}", "client.timeout", &i1) == 0)
|
||||
g_session.timeout = i1;
|
||||
|
||||
// persistent HF field timeout (seconds)
|
||||
if (json_unpack_ex(root, &up_error, 0, "{s:i}", "hf.field.timeout_sec", &i1) == 0)
|
||||
g_session.hf_field_timeout_sec = (i1 > 0) ? (uint32_t)i1 : 0;
|
||||
|
||||
// MQTT server
|
||||
if (json_unpack_ex(root, &up_error, 0, "{s:s}", "mqtt.server", &s1) == 0)
|
||||
setDefaultMqttServer(s1);
|
||||
@@ -671,6 +677,14 @@ static void showClientTimeoutState(void) {
|
||||
PrintAndLogEx(INFO, " communication timeout... " _GREEN_("%u") " ms", g_session.timeout);
|
||||
}
|
||||
|
||||
static void showFieldTimeoutState(void) {
|
||||
if (g_session.hf_field_timeout_sec == 0) {
|
||||
PrintAndLogEx(INFO, " HF field timeout........ " _WHITE_("off"));
|
||||
} else {
|
||||
PrintAndLogEx(INFO, " HF field timeout........ " _GREEN_("%u") " s", g_session.hf_field_timeout_sec);
|
||||
}
|
||||
}
|
||||
|
||||
static void showMqttServer(prefShowOpt_t opt) {
|
||||
if ((g_session.mqtt_server == NULL) || (strcmp(g_session.mqtt_server, "") == 0)) {
|
||||
PrintAndLogEx(INFO, " MQTT server.............%s "_WHITE_("not set"), pref_show_status_msg(opt));
|
||||
@@ -1067,6 +1081,50 @@ static int setCmdClientTimeout(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int setCmdHfFieldTimeout(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "prefs set hf.field.timeout_sec",
|
||||
"Set persistent preference of PM3 HF field inactivity timeout",
|
||||
"prefs set hf.field.timeout_sec --sec 0 --> disable HF field auto timeout\n"
|
||||
"prefs set hf.field.timeout_sec --sec 5 --> turn HF field off after 5 seconds of inactivity\n"
|
||||
"prefs set hf.field.timeout_sec --sec 300 --> turn HF field off after 5 minutes of inactivity\n"
|
||||
"prefs set hf.field.timeout_sec --sec 900 --> turn HF field off after 15 minutes of inactivity\n");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int0("s", "sec", "<sec>", "HF field inactivity timeout in seconds"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
int32_t arg = arg_get_int_def(ctx, 1, -1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (arg < 0) {
|
||||
showFieldTimeoutState();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t new_value = (uint32_t)arg;
|
||||
|
||||
if (g_session.hf_field_timeout_sec != new_value) {
|
||||
showFieldTimeoutState();
|
||||
g_session.hf_field_timeout_sec = new_value;
|
||||
showFieldTimeoutState();
|
||||
preferences_save();
|
||||
} else {
|
||||
showFieldTimeoutState();
|
||||
}
|
||||
|
||||
if (g_session.pm3_present) {
|
||||
int res = SetHfFieldTimeout(g_session.hf_field_timeout_sec, false);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(WARNING, "Failed to apply HF field timeout to connected PM3");
|
||||
}
|
||||
}
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int setCmdHint(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
@@ -1517,6 +1575,22 @@ static int getCmdClientTimeout(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int getCmdHfFieldTimeout(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "prefs get hf.field.timeout_sec",
|
||||
"Get preference of PM3 HF field inactivity timeout",
|
||||
"prefs get hf.field.timeout_sec"
|
||||
);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
showFieldTimeoutState();
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int getCmdMqtt(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "prefs get mqtt",
|
||||
@@ -1540,6 +1614,7 @@ static command_t CommandTableGet[] = {
|
||||
{"client.debug", getCmdDebug, AlwaysAvailable, "Get client debug level preference"},
|
||||
{"client.delay", getCmdExeDelay, AlwaysAvailable, "Get client execution delay preference"},
|
||||
{"client.timeout", getCmdClientTimeout, AlwaysAvailable, "Get client execution delay preference"},
|
||||
{"hf.field.timeout_sec", getCmdHfFieldTimeout, AlwaysAvailable, "Get PM3 HF field inactivity timeout preference"},
|
||||
{"color", getCmdColor, AlwaysAvailable, "Get color support preference"},
|
||||
{"savepaths", getCmdSavePaths, AlwaysAvailable, "Get file folder "},
|
||||
// {"devicedebug", getCmdDeviceDebug, AlwaysAvailable, "Get device debug level"},
|
||||
@@ -1557,6 +1632,7 @@ static command_t CommandTableSet[] = {
|
||||
{"client.debug", setCmdDebug, AlwaysAvailable, "Set client debug level"},
|
||||
{"client.delay", setCmdExeDelay, AlwaysAvailable, "Set client execution delay"},
|
||||
{"client.timeout", setCmdClientTimeout, AlwaysAvailable, "Set client communication timeout"},
|
||||
{"hf.field.timeout_sec", setCmdHfFieldTimeout, AlwaysAvailable, "Set PM3 HF field inactivity timeout"},
|
||||
|
||||
{"color", setCmdColor, AlwaysAvailable, "Set color support"},
|
||||
{"emoji", setCmdEmoji, AlwaysAvailable, "Set emoji display"},
|
||||
@@ -1630,6 +1706,7 @@ static int CmdPrefShow(const char *Cmd) {
|
||||
showClientExeDelayState();
|
||||
showOutputState(prefShowNone);
|
||||
showClientTimeoutState();
|
||||
showFieldTimeoutState();
|
||||
showMqttServer(prefShowNone);
|
||||
showMqttPort(prefShowNone);
|
||||
showMqttTopic(prefShowNone);
|
||||
|
||||
@@ -63,6 +63,7 @@ typedef struct {
|
||||
char *history_path;
|
||||
pm3_device_t *current_device;
|
||||
uint32_t timeout;
|
||||
uint32_t hf_field_timeout_sec;
|
||||
char *mqtt_server;
|
||||
char *mqtt_port;
|
||||
char *mqtt_topic;
|
||||
|
||||
@@ -97,7 +97,13 @@ void SpinDelay(int ms) {
|
||||
// SpinDelay(1000);
|
||||
// ti = GetTickCount() - ti;
|
||||
// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
|
||||
// Increments whenever StartTickCount() reconfigures/resets RTTC.
|
||||
// Callers can use this to detect that previously saved tick deltas are no longer valid.
|
||||
static uint32_t g_tickcount_label = 0;
|
||||
|
||||
void StartTickCount(void) {
|
||||
g_tickcount_label++;
|
||||
|
||||
// This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
|
||||
// We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register.
|
||||
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
|
||||
@@ -122,6 +128,14 @@ uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks) {
|
||||
return (UINT32_MAX - start_ticks) + stop_ticks;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get current RTTC counter label.
|
||||
* If counter config changes between calls, the value is incremented.
|
||||
*/
|
||||
uint32_t GetTickCountLabel(void) {
|
||||
return g_tickcount_label;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Timer for iso14443 commands. Uses ssp_clk from FPGA
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@@ -47,6 +47,7 @@ void SpinDelayUsPrecision(int us); // precision 0.6us , running for 43ms before
|
||||
void StartTickCount(void);
|
||||
uint32_t RAMFUNC GetTickCount(void);
|
||||
uint32_t RAMFUNC GetTickCountDelta(uint32_t start_ticks);
|
||||
uint32_t GetTickCountLabel(void);
|
||||
|
||||
void ResetUSClock(void);
|
||||
void SpinDelayCountUs(uint32_t us);
|
||||
|
||||
+14
-1
@@ -118,7 +118,8 @@ Characteristics:
|
||||
|
||||
* 1 kHz, 32b (49 days), if used with 16b: 65s
|
||||
* Configured at boot (or TIA) with `StartTickCount()`
|
||||
* Time events with `GetTickCount()`/`GetTickCountDeltaDelta()`, see example
|
||||
* Time events with `GetTickCount()`/`GetTickCountDelta()`, see example
|
||||
* Each change in configuration of the clock increments the label value, retrievable through `GetTickCountLabel()`
|
||||
* Coarse, based on the ~32kHz RC slow clock with some adjustment factor computed by TIA
|
||||
* Maybe 2.5% error, can increase if temperature conditions change and no TIA is recomputed
|
||||
* If TimingIntervalAcquisition() is called later, StartTickCount() is called again and RTC is reset
|
||||
@@ -131,12 +132,24 @@ uint32_t ti = GetTickCount();
|
||||
uint32_t delta = GetTickCountDelta(ti);
|
||||
```
|
||||
|
||||
If `StartTickCount()` may run between two reads (e.g. via TIA), pair tick with a label:
|
||||
|
||||
```
|
||||
uint32_t label = GetTickCountLabel();
|
||||
uint32_t ti = GetTickCount();
|
||||
...do stuff...
|
||||
if (label == GetTickCountLabel()) {
|
||||
uint32_t delta = GetTickCountDelta(ti);
|
||||
}
|
||||
```
|
||||
|
||||
Current usages:
|
||||
|
||||
* cheap random for nonces, e.g. `prng_successor(GetTickCount(), 32)`
|
||||
* rough timing of some operations, only for informative purposes
|
||||
* timeouts
|
||||
* USB connection speed measure
|
||||
* Optional HF field inactivity timeout
|
||||
|
||||
## Occasional PWM timer
|
||||
^[Top](#top)
|
||||
|
||||
@@ -531,6 +531,7 @@ typedef struct {
|
||||
#define CMD_TIA 0x0117
|
||||
#define CMD_BREAK_LOOP 0x0118
|
||||
#define CMD_SET_TEAROFF 0x0119
|
||||
#define CMD_SET_HF_FIELD_TIMEOUT 0x011A
|
||||
#define CMD_GET_DBGMODE 0x0120
|
||||
|
||||
// RDV40, Flash memory operations
|
||||
|
||||
Reference in New Issue
Block a user