aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/usrp3/lib/cron.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/usrp3/lib/cron.c')
-rw-r--r--firmware/usrp3/lib/cron.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/firmware/usrp3/lib/cron.c b/firmware/usrp3/lib/cron.c
new file mode 100644
index 000000000..24b8feb4e
--- /dev/null
+++ b/firmware/usrp3/lib/cron.c
@@ -0,0 +1,92 @@
+//
+// Copyright 2014 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#include "cron.h"
+
+//Counter specific
+static cron_counter_fetcher_t cron_fetch_counter;
+static uint32_t cron_counter_freq;
+
+//Cron job specific
+typedef struct {
+ uint32_t tick_interval;
+ uint32_t last_tick_count;
+} cron_job_t;
+
+static cron_job_t cron_job_table[CRON_MAX_JOBS];
+
+void cron_init(const cron_counter_fetcher_t fetch_counter, uint32_t counter_freq)
+{
+ cron_fetch_counter = fetch_counter;
+ cron_counter_freq = counter_freq;
+
+ for (int i = 0; i < CRON_MAX_JOBS; i++) {
+ cron_job_table[i].tick_interval = 0;
+ }
+}
+
+uint32_t cron_get_ticks()
+{
+ return cron_fetch_counter();
+}
+
+uint32_t get_elapsed_time(uint32_t start_ticks, uint32_t stop_ticks, cron_time_unit_t unit)
+{
+ return ((stop_ticks - start_ticks) / cron_counter_freq) * ((uint32_t)unit);
+}
+
+void sleep_ticks(uint32_t ticks)
+{
+ if (ticks == 0) return; //Handle the 0 delay case quickly
+
+ const uint32_t ticks_begin = cron_fetch_counter();
+ while(cron_fetch_counter() - ticks_begin < ticks) {
+ /*NOP: Spinloop*/
+ }
+}
+
+void sleep_us(uint32_t duration)
+{
+ sleep_ticks((duration * (cron_counter_freq/1000000)));
+}
+
+void sleep_ms(uint32_t duration)
+{
+ sleep_ticks((duration * (cron_counter_freq/1000)));
+}
+
+void cron_job_init(uint32_t job_id, uint32_t interval_ms)
+{
+ cron_job_table[job_id].tick_interval = (interval_ms * (cron_counter_freq/1000));
+ cron_job_table[job_id].last_tick_count = 0;
+}
+
+bool cron_job_run_due(uint32_t job_id)
+{
+ uint32_t new_tick_count = cron_fetch_counter();
+ bool run_job = (new_tick_count - cron_job_table[job_id].last_tick_count) >=
+ cron_job_table[job_id].tick_interval;
+
+ if (run_job) {
+ //If the job is due to run, update the tick count for the next run
+ //The assumption here is that the caller will actually run their job
+ //when the return value is true. If not, the caller just missed this
+ //iteration and will have to option to run the job in the next pass through.
+ cron_job_table[job_id].last_tick_count = new_tick_count;
+ }
+ return run_job;
+}