Sansa Connect: Discard invalid monotime reads

Read monotime twice in a row and only accept the value if it matches or
the two reads are 1 second apart.

Change-Id: Ibd289103a20404dd1b2bbd131fdfa8905852c788
This commit is contained in:
Tomasz Moń 2021-06-27 13:14:11 +02:00
parent a4ab636423
commit 1b81bd8a61
No known key found for this signature in database
GPG key ID: 92BA8820D4D517C8

View file

@ -120,9 +120,10 @@ static bool input_interrupt_pending;
#define MONOTIME_OFFSET_FILE ROCKBOX_DIR "/monotime_offset.dat"
static uint32_t monotime_offset;
/* Buffer last read monotime value. Reading monotime takes
* atleast 700 us so the tick counter is used together with
* atleast 1400 us so the tick counter is used together with
* last read monotime value to return current time.
*/
static bool monotime_available;
static uint32_t monotime_value;
static unsigned long monotime_value_tick;
@ -521,16 +522,6 @@ bool charging_state(void)
return (avr_battery_status & BATTERY_STATUS_CHARGING) != 0;
}
static uint32_t avr_hid_get_monotime(void)
{
uint8_t tmp[4];
if (avr_execute_command(CMD_MONOTIME, tmp, sizeof(tmp)))
{
return (tmp[0]) | (tmp[1] << 8) | (tmp[2] << 16) | (tmp[3] << 24);
}
return 0;
}
static void avr_hid_enable_wheel(void)
{
uint8_t enable = 0x01;
@ -651,22 +642,48 @@ static bool write_monotime_offset(void)
static void read_monotime(void)
{
uint32_t value = avr_hid_get_monotime();
uint8_t tmp[4];
uint32_t t1, t2;
if (!avr_execute_command(CMD_MONOTIME, tmp, sizeof(tmp)))
{
return;
}
t1 = (tmp[0]) | (tmp[1] << 8) | (tmp[2] << 16) | (tmp[3] << 24);
if (!avr_execute_command(CMD_MONOTIME, tmp, sizeof(tmp)))
{
return;
}
t2 = (tmp[0]) | (tmp[1] << 8) | (tmp[2] << 16) | (tmp[3] << 24);
if ((t1 == t2) || (t1 + 1 == t2))
{
int flags = disable_irq_save();
monotime_value = value;
monotime_value = t1;
monotime_value_tick = current_tick;
restore_irq(flags);
monotime_available = true;
}
}
static time_t get_timestamp(void)
{
time_t timestamp;
if (!monotime_available)
{
read_monotime();
}
if (monotime_available)
{
int flags = disable_irq_save();
timestamp = monotime_value;
timestamp += monotime_offset;
timestamp += ((current_tick - monotime_value_tick) / HZ);
restore_irq(flags);
return timestamp;
}
return 0;
}
void rtc_init(void)