memcpy(avr->flash + address, code, size);
}
+/**
+ * Accumulates sleep requests (and returns a sleep time of 0) until
+ * a minimum count of requested sleep microseconds are reached
+ * (low amounts cannot be handled accurately).
+ */
+static inline uint32_t avr_pending_sleep_usec(avr_t * avr, avr_cycle_count_t howLong)
+{
+ avr->sleep_usec += avr_cycles_to_usec(avr, howLong);
+ uint32_t usec = avr->sleep_usec;
+ if (usec > 200) {
+ avr->sleep_usec = 0;
+ return usec;
+ }
+ return 0;
+}
+
void avr_callback_sleep_gdb(avr_t * avr, avr_cycle_count_t howLong)
{
- uint32_t usec = avr_cycles_to_usec(avr, howLong);
+ uint32_t usec = avr_pending_sleep_usec(avr, howLong);
while (avr_gdb_processor(avr, usec))
;
}
void avr_callback_sleep_raw(avr_t * avr, avr_cycle_count_t howLong)
{
- uint32_t usec = avr_cycles_to_usec(avr, howLong);
- usleep(usec);
+ uint32_t usec = avr_pending_sleep_usec(avr, howLong);
+ if (usec > 0) {
+ usleep(usec);
+ }
}
void avr_callback_run_raw(avr_t * avr)
// not only to "cycles that runs" but also "cycles that might have run"
// like, sleeping.
avr_cycle_count_t cycle; // current cycle
+
+ /**
+ * Sleep requests are accumulated in sleep_usec until the minimum sleep value
+ * is reached, at which point sleep_usec is cleared and the sleep request
+ * is passed on to the operating system.
+ */
+ uint32_t sleep_usec;
// called at init time
void (*init)(struct avr_t * avr);