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:
parent
a4ab636423
commit
1b81bd8a61
1 changed files with 39 additions and 22 deletions
|
@ -120,9 +120,10 @@ static bool input_interrupt_pending;
|
||||||
#define MONOTIME_OFFSET_FILE ROCKBOX_DIR "/monotime_offset.dat"
|
#define MONOTIME_OFFSET_FILE ROCKBOX_DIR "/monotime_offset.dat"
|
||||||
static uint32_t monotime_offset;
|
static uint32_t monotime_offset;
|
||||||
/* Buffer last read monotime value. Reading monotime takes
|
/* 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.
|
* last read monotime value to return current time.
|
||||||
*/
|
*/
|
||||||
|
static bool monotime_available;
|
||||||
static uint32_t monotime_value;
|
static uint32_t monotime_value;
|
||||||
static unsigned long monotime_value_tick;
|
static unsigned long monotime_value_tick;
|
||||||
|
|
||||||
|
@ -521,16 +522,6 @@ bool charging_state(void)
|
||||||
return (avr_battery_status & BATTERY_STATUS_CHARGING) != 0;
|
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)
|
static void avr_hid_enable_wheel(void)
|
||||||
{
|
{
|
||||||
uint8_t enable = 0x01;
|
uint8_t enable = 0x01;
|
||||||
|
@ -651,22 +642,48 @@ static bool write_monotime_offset(void)
|
||||||
|
|
||||||
static void read_monotime(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();
|
int flags = disable_irq_save();
|
||||||
monotime_value = value;
|
monotime_value = t1;
|
||||||
monotime_value_tick = current_tick;
|
monotime_value_tick = current_tick;
|
||||||
restore_irq(flags);
|
restore_irq(flags);
|
||||||
|
monotime_available = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static time_t get_timestamp(void)
|
static time_t get_timestamp(void)
|
||||||
{
|
{
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
|
if (!monotime_available)
|
||||||
|
{
|
||||||
|
read_monotime();
|
||||||
|
}
|
||||||
|
if (monotime_available)
|
||||||
|
{
|
||||||
int flags = disable_irq_save();
|
int flags = disable_irq_save();
|
||||||
timestamp = monotime_value;
|
timestamp = monotime_value;
|
||||||
timestamp += monotime_offset;
|
timestamp += monotime_offset;
|
||||||
timestamp += ((current_tick - monotime_value_tick) / HZ);
|
timestamp += ((current_tick - monotime_value_tick) / HZ);
|
||||||
restore_irq(flags);
|
restore_irq(flags);
|
||||||
return timestamp;
|
return timestamp;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rtc_init(void)
|
void rtc_init(void)
|
||||||
|
|
Loading…
Reference in a new issue