summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorTomasz Moń <desowin@gmail.com>2021-06-27 13:14:11 +0200
committerTomasz Moń <desowin@gmail.com>2021-06-27 13:14:11 +0200
commit1b81bd8a6153314aadc1144d55a7c02eb11111c5 (patch)
treefd0ac1e911b1f7406dbb2f0279a6b2fbf7ad599f /firmware/target
parenta4ab6364236b4453e93b12ecba1e9f389f6edd2f (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.c61
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)