summaryrefslogtreecommitdiff
path: root/cesar/cp/beacon/ntb/src/ntb.c
diff options
context:
space:
mode:
authorlaranjeiro2008-09-24 14:42:13 +0000
committerlaranjeiro2008-09-24 14:42:13 +0000
commit082641b0ac2cc1243f269df3ed1fea67992cbcda (patch)
tree74d68f3ff3bcef1fd2503ddf0d9e26bd099ea6d7 /cesar/cp/beacon/ntb/src/ntb.c
parente159999f3f337cc5ad2d29d442c87969a085a6ca (diff)
cp/beacon/ntb: Rewrote the ntb module.
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@3068 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/cp/beacon/ntb/src/ntb.c')
-rw-r--r--cesar/cp/beacon/ntb/src/ntb.c153
1 files changed, 153 insertions, 0 deletions
diff --git a/cesar/cp/beacon/ntb/src/ntb.c b/cesar/cp/beacon/ntb/src/ntb.c
new file mode 100644
index 0000000000..a19e023c17
--- /dev/null
+++ b/cesar/cp/beacon/ntb/src/ntb.c
@@ -0,0 +1,153 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/ntb.src/ntb.c
+ * \brief NTB clock synchronization.
+ * \ingroup cp_beacon
+ */
+#include "common/std.h"
+
+#include "cp/cp.h"
+#include "cp/beacon/ntb/ntb.h"
+
+#include "cp/beacon/ntb/inc/context.h"
+#include "cp/inc/context.h"
+
+#include "string.h"
+
+#define CP_BEACON_NTB_DEFAULT_FACTOR 1000000.0
+
+/** Frequency error function.
+ * freqError the previous value of the frequency error computed.
+ * n Number of iterrations.
+ * bts the Beacon Time Stamp array, index 1 corresponds to the previous
+ * beacon time stamp, index 2 corresponds to the actual beacon time stamp.
+ * ltmr The Local timer, index 1 corresponds to the previous ltmr and index 2
+ * corresponds to the actual ltmr.
+ * wf, w0 weight of the form 1/2 k with k a positive integer.
+ */
+static void
+cp_beacon_ntb_frequency_error (cp_t *ctx, u32 bts, u32 ltmr)
+{
+ float bts_diff;
+ float ltmr_diff;
+ float os;
+ float fe;
+
+ bts_diff = ctx->ntb.bts - bts;
+ ltmr_diff = ctx->ntb.ltmr - ltmr;
+ os = 0;
+ fe = 0;
+
+ if (ctx->ntb.first_shoot)
+ {
+ ctx->ntb.first_shoot = false;
+ fe = bts_diff / ltmr_diff - 1;
+ os = bts - ltmr;
+ }
+ else
+ {
+ fe = ctx->ntb.freq_error
+ + 0.25 * (bts_diff / ltmr_diff - 1 - ctx->ntb.freq_error);
+ os = ctx->ntb.offset + fe * ltmr_diff
+ + 0.25 * ((bts - ltmr) - (ctx->ntb.offset + fe * ltmr_diff));
+ }
+
+ ctx->ntb.freq_error = fe;
+ ctx->ntb.offset = os;
+ ctx->ntb.bts = bts;
+ ctx->ntb.ltmr = ltmr;
+
+}
+
+/** Compute the new value of the local timer from the frequency error and the
+ * offset.
+ * \param ltmr array containing the current value of the previous ltmr
+ * computed and the current ltmr.
+ * \param offset the offset computed by the frequency_error_function.
+ * \param freq_error the frequency error compute by the frequency_error
+ * function.
+ * \return the ltmr estimated.
+ */
+static float
+cp_beacon_ntb_accurate_ltmr (cp_t *ctx, float ltmr)
+{
+ float ntb_sta = 0;
+ float ltmri = ctx->ntb.ltmr;
+
+ ntb_sta = (1+ ctx->ntb.freq_error) * (ltmri - ltmr)
+ + ltmr + ctx->ntb.offset;
+ ltmri = (ntb_sta + ctx->ntb.freq_error * ltmr
+ - ctx->ntb.offset) / ( 1 + ctx->ntb.freq_error );
+
+ ctx->ntb.ltmr = ltmri;
+ return ltmri;
+}
+
+/**
+ * Initialise the NTB module.
+ * \param ctx the CP context.
+ */
+void
+cp_beacon_ntb_init (cp_t *ctx)
+{
+ dbg_assert (ctx);
+
+ memset (&ctx->ntb, 0, sizeof (cp_beacon_ntb_t));
+ ctx->ntb.first_shoot = true;
+}
+
+/**
+ * Uninitialise the NTB module.
+ * \param ctx the CP context.
+ */
+void
+cp_beacon_ntb_uninit (cp_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
+/*
+ * Synchronize local clock to be as close as possible to estimated value
+ * of the NTB clock reference.
+ *
+ * \param ctx pointer to CP context
+ * \param beacon_bts beacon time stamp
+ * \param beacon_sta_ltmr STA local time captured when receiving beacon
+ */
+void
+cp_beacon_ntb_clk_sync (cp_t * ctx, u32 beacon_bts,
+ u32 beacon_sta_ltmr)
+{
+ float ltmri;
+ float decimal_num;
+ uint numerator;
+ dbg_assert (ctx);
+
+ cp_beacon_ntb_frequency_error (ctx, beacon_bts, beacon_sta_ltmr);
+ ltmri = cp_beacon_ntb_accurate_ltmr (ctx, beacon_sta_ltmr);
+
+ /* Update the u32 "ntb_offset_tck" field (NTB offset). */
+ ctx->mac_config.ntb_offset_tck = (u32) ctx->ntb.offset;
+
+ /* Update the frequency error in the Phy. */
+ phy_sysclock_set_freqerror (ctx->phy,
+ ctx->ntb.freq_error
+ * CP_BEACON_NTB_DEFAULT_FACTOR);
+
+ /* Compute the new numerator. */
+ decimal_num = CP_BEACON_NTB_DEFAULT_FACTOR * (ctx->ntb.freq_error + 1.0);
+ numerator = decimal_num + 0.5;
+ if (numerator != ctx->ntb.sta_num)
+ {
+ /* Update the numerator value in the PRATIC config ! */
+ phy_clock_set_numerator (ctx->phy, numerator);
+ }
+ ctx->ntb.sta_num = numerator;
+}
+