diff options
author | Tomasz Moń <desowin@gmail.com> | 2021-06-27 13:14:11 +0200 |
---|---|---|
committer | Tomasz Moń <desowin@gmail.com> | 2021-06-27 13:14:11 +0200 |
commit | 1b81bd8a6153314aadc1144d55a7c02eb11111c5 (patch) | |
tree | fd0ac1e911b1f7406dbb2f0279a6b2fbf7ad599f /firmware/target | |
parent | a4ab6364236b4453e93b12ecba1e9f389f6edd2f (diff) |
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
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c index a72faea7be..94ffcdf195 100644 --- a/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c +++ b/firmware/target/arm/tms320dm320/sansa-connect/avr-sansaconnect.c @@ -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(); - int flags = disable_irq_save(); - monotime_value = value; - monotime_value_tick = current_tick; - restore_irq(flags); + 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 = t1; + monotime_value_tick = current_tick; + restore_irq(flags); + monotime_available = true; + } } static time_t get_timestamp(void) { time_t timestamp; - int flags = disable_irq_save(); - timestamp = monotime_value; - timestamp += monotime_offset; - timestamp += ((current_tick - monotime_value_tick) / HZ); - restore_irq(flags); - return 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) |