summaryrefslogtreecommitdiff
path: root/cesar/cl/src
diff options
context:
space:
mode:
authormercadie2009-09-07 15:14:33 +0000
committermercadie2009-09-07 15:14:33 +0000
commit6e7d5f934d985868adf40e78edeb2310db9543f3 (patch)
treed10f276a1b367b23c01bf7e00c2d4500fc8a80d7 /cesar/cl/src
parentf64fbc68ed24e960efeb12740e0be2db30e9375d (diff)
* delivery of data_rate module in cl
- data-rate calculation using data size and elapsed time - data_rate test git-svn-id: svn+ssh://pessac/svn/cesar/trunk@5440 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/cl/src')
-rw-r--r--cesar/cl/src/data_rate.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/cesar/cl/src/data_rate.c b/cesar/cl/src/data_rate.c
new file mode 100644
index 0000000000..796d131bc0
--- /dev/null
+++ b/cesar/cl/src/data_rate.c
@@ -0,0 +1,84 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2009 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cl/src/data_rate.c
+ * \brief Data rate functions.
+ * \ingroup cl
+ */
+
+#include "common/std.h"
+#include "cl/data_rate.h"
+#include <cyg/kernel/kapi.h>
+#include "hal/phy/phy.h"
+#include "mac/common/ntb.h"
+
+#define div(a, b) ((a+((b)/2))/(b))
+
+void
+data_rate_init (data_rate_t* p_dr)
+{
+ p_dr->data_rate = 0;
+ p_dr->ecos_time = cyg_current_time ();
+ p_dr->phy_time = mac_date ();
+}
+
+void
+data_rate_update_info (data_rate_t *p_dr, uint data_size)
+{
+ static u32 phy_period = 0;
+ static u64 ecos_period = 0;
+ u64 new_ecos_time; /* in ecos tick (10ms so far) */
+ u32 new_phy_time; /* in phy ticks (40ns so far) */
+ u32 interval; /* delay between last time and now (in phy ticks) */
+ u64 new_rate; /* in octets per phy ticks */
+
+ /* This is the period (in ns) over which the data rate is evaluated */
+ u64 data_rate_period = 1000000000LL;
+
+ if (!phy_period)
+ {
+ /* evaluate the periods phy tick counts only once for all */
+ cyg_resolution_t res =
+ cyg_clock_get_resolution (cyg_real_time_clock ());
+ ecos_period = div(res.divisor*data_rate_period, res.dividend);
+ phy_period = div(data_rate_period, 40);
+ }
+
+ /* Get delay between last time data rate was evaluated and now */
+ new_ecos_time = cyg_current_time();
+ new_phy_time = mac_date ();
+
+ if ((new_ecos_time - p_dr->ecos_time) > ecos_period)
+ {
+ /* maximise the delay */
+ interval = phy_period;
+ }
+ else
+ {
+ /* mesure delay with phy time */
+ interval = new_phy_time - p_dr->phy_time;
+ }
+
+ if (interval >= phy_period)
+ {
+ /* mesure the new rate over one period */
+ new_rate = div(data_size , phy_period);
+ }
+ else
+ {
+ /* fine mesure of the delay with phy clock */
+ new_rate = div(p_dr->data_rate * (phy_period - interval), phy_period)
+ + data_size;
+ }
+
+ /* update the data_rate structure */
+ p_dr->data_rate = new_rate;
+ p_dr->phy_time = new_phy_time;
+ p_dr->ecos_time = new_ecos_time;
+}
+