summaryrefslogtreecommitdiff
path: root/cesar/bsu/aclf
diff options
context:
space:
mode:
authorlaranjeiro2010-05-17 09:57:08 +0000
committerlaranjeiro2010-05-17 09:57:08 +0000
commit6a82d94088e4bdd1e34598c1b1a347fe57f49ddb (patch)
tree9e4d3526dbbef5f591ad804a5a188bb0f301aac0 /cesar/bsu/aclf
parentb53c50940132dd6e6d6118d477cd5e7727a5689e (diff)
cesar/bsu/aclf: add a timer to compute beacon period start date
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@7060 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/bsu/aclf')
-rw-r--r--cesar/bsu/aclf/aclf.h55
-rw-r--r--cesar/bsu/aclf/src/aclf.c182
-rw-r--r--cesar/bsu/aclf/test/utest/src/bpsd.c6
-rw-r--r--cesar/bsu/aclf/test/utest/src/common.c4
-rw-r--r--cesar/bsu/aclf/test/utest/src/freq.c3
-rw-r--r--cesar/bsu/aclf/test/utest/src/misc.c51
6 files changed, 208 insertions, 93 deletions
diff --git a/cesar/bsu/aclf/aclf.h b/cesar/bsu/aclf/aclf.h
index f801139d8c..abf8a26113 100644
--- a/cesar/bsu/aclf/aclf.h
+++ b/cesar/bsu/aclf/aclf.h
@@ -15,6 +15,7 @@
* All functions needed to track the frequency variation of the AC Line.
*/
#include "hal/phy/phy.h"
+#include "hal/timer/timer.h"
#include "mac/common/config.h"
#include "mac/common/timings.h"
#include "common/defs/homeplugAV.h"
@@ -93,6 +94,12 @@ struct bsu_aclf_t
* Last value read in PRATIC register.
*/
u32 date;
+ /** Track the ACL. */
+ bool aclsc;
+ /** Hal timer context. */
+ hal_timer_t *hal_timer;
+ /** Timer instance. */
+ hal_timer_instance_t timer;
};
typedef struct bsu_aclf_t bsu_aclf_t;
@@ -102,10 +109,11 @@ BEGIN_DECLS
* Initialise the module.
* \param phy the phy context.
* \param mac_config the mac config structure.
+ * \param timer the hal_timer.
* \return the module context pointer.
*/
bsu_aclf_t*
-bsu_aclf_init (phy_t *phy, mac_config_t *mac_config);
+bsu_aclf_init (phy_t *phy, mac_config_t *mac_config, hal_timer_t *timer);
/**
* Uninitialise the module.
@@ -115,18 +123,6 @@ void
bsu_aclf_uninit (bsu_aclf_t *ctx);
/**
- * Compute the frequency of the power line using the PRATIC register.
- * \param ctx the module context.
- *
- * It shall read the PRATIC register twice with a gap of BSU_ACLF_ZC_50. This
- * function shall update the data in the object.
- *
- * \warn If the medium is a coaxial cable, the 50Hz will be chosen.
- */
-void
-bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx);
-
-/**
* Compute the beacon period start date from the data contained in the
* beacon.
* \param ctx the module context.
@@ -140,23 +136,6 @@ bsu_aclf_compute_beacon_period_start_date (bsu_aclf_t *ctx, const u32 bts_ntb,
const u32 bpsto);
/**
- * Shift the date to correspond to the current date.
- * \param ctx the module context.
- *
- * Used when the station is acting as STA and the central beacon has not been
- * received.
- */
-void
-bsu_aclf_shift_beacon_period_start_date (bsu_aclf_t *ctx);
-
-/**
- * Compute the beacon period start date from the AC Line.
- * \param ctx the module context.
- */
-void
-bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx);
-
-/**
* Get the beacon period start time.
* \param ctx the module context.
* \param bpsd the array to store the beacon period start time values.
@@ -193,6 +172,22 @@ bsu_aclf_beacon_period_start_date_next (bsu_aclf_t *ctx);
u32
bsu_aclf_beacon_period (bsu_aclf_t *ctx);
+/**
+ * ACLF must synchronise on the ACL frequency.
+ * \param ctx the module context.
+ * \param aclsc the boolean to inform the ACL.
+ */
+void
+bsu_aclf_aclsc (bsu_aclf_t *ctx, bool aclsc);
+
+/**
+ * Activate the BSU ACLF
+ * \param ctx the module context.
+ * \param status true to activate, false otherwise.
+ */
+void
+bsu_aclf_activate (bsu_aclf_t *ctx, bool status);
+
END_DECLS
#endif /* bsu_aclf_aclf_h */
diff --git a/cesar/bsu/aclf/src/aclf.c b/cesar/bsu/aclf/src/aclf.c
index 6f80500b65..04686695e7 100644
--- a/cesar/bsu/aclf/src/aclf.c
+++ b/cesar/bsu/aclf/src/aclf.c
@@ -55,24 +55,97 @@ bsu_aclf_compute_beacon_period_from_acl (bsu_aclf_t *ctx)
ctx->beacon_period += BSU_ACLF_WP * ((s32) diff - (s32)ctx->beacon_period);
}
-bsu_aclf_t*
-bsu_aclf_init (phy_t *phy, mac_config_t *mac_config)
+/**
+ * Shift the date to correspond to the current date.
+ * \param ctx the module context.
+ *
+ * Used when the station is acting as STA and the central beacon has not been
+ * received.
+ */
+void
+bsu_aclf_shift_beacon_period_start_date (bsu_aclf_t *ctx)
{
- bsu_aclf_t *ctx = &bsu_aclf_global;
- dbg_assert (phy);
- dbg_assert (mac_config);
- memset (ctx, 0, sizeof (bsu_aclf_t));
- ctx->phy = phy;
- ctx->mac_config = mac_config;
- return ctx;
+ uint i;
+ dbg_assert (ctx);
+ u32 now = phy_date ();
+ if (lesseq_mod2p32 (ctx->bpsd[1], now))
+ {
+ for (i = 0; i < BSU_ACLF_BPSD_NB - 1; i++)
+ ctx->bpsd[i] = ctx->bpsd[i+1];
+ ctx->bpsd[i] += ctx->beacon_period;
+ }
}
+/**
+ * Compute the beacon period start date from the AC Line.
+ * \param ctx the module context.
+ */
void
-bsu_aclf_uninit (bsu_aclf_t *ctx)
+bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx)
{
dbg_assert (ctx);
+ dbg_assert (ctx->aclsc);
+ uint i;
+ u32 now = phy_date ();
+ u32 bts;
+ int bto;
+
+ bsu_aclf_compute_beacon_period_from_acl (ctx);
+ /* First time the function is called. */
+ if (ctx->bpsd[0] == ctx->bpsd[1])
+ {
+ ctx->bpsd[0] = now;
+ for (i = 1; i < BSU_ACLF_BPSD_NB; i++)
+ ctx->bpsd[i] = ctx->bpsd[i-1] + ctx->beacon_period;
+ }
+ /* Compute only if the current beacon period is over. */
+ else if (lesseq_mod2p32 (ctx->bpsd[1], now))
+ {
+ /* Update the beacon period start time. */
+ for (i = 0; i < BSU_ACLF_BPSD_NB - 1; i++)
+ ctx->bpsd[i] = ctx->bpsd[i+1];
+ /* Add on the last beacon period start date the beacon period
+ * estimated. */
+ ctx->bpsd[BSU_ACLF_BPSD_NB - 1] += ctx->beacon_period;
+ }
+ /* Compute the BTO using the theoretical beacon period value.
+ * BTO is computed from bpsd[1]. */
+ bts = ctx->bpsd[1];
+ for (i = 0; i < HPAV_BEACON_BTO_NB; i++)
+ {
+ bto = ctx->bpsd[i+2] - bts - (i+1)*ctx->bp;
+ /* Does bto overflowed ? */
+ if (ABS(bto) >> 15 == 0)
+ ctx->bto[i] = bto;
+ else
+ ctx->bto[i] = HPAV_BEACON_BTO_INVALID;
+ }
+}
+
+/**
+ * Timer event function call.
+ * \param user_data the module context.
+ */
+void
+bsu_aclf_timer_event (void *user_data)
+{
+ bsu_aclf_t *ctx = (bsu_aclf_t*) user_data;
+ if (ctx->aclsc)
+ bsu_aclf_ac_compute_beacon_period_start_date (ctx);
+ else
+ bsu_aclf_shift_beacon_period_start_date (ctx);
+ hal_timer_instance_program (ctx->hal_timer, &ctx->timer, ctx->bpsd[1]);
}
+/**
+ * Compute the frequency of the power line using the PRATIC register.
+ * \param ctx the module context.
+ *
+ * It shall read the PRATIC register twice with a gap of BSU_ACLF_ZC_50. This
+ * function shall update the data in the object.
+ *
+ * \warn If the medium is a coaxial cable, the 50Hz will be chosen.
+ */
void
bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx)
{
@@ -104,6 +177,26 @@ bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx)
ctx->date = newzc;
}
+bsu_aclf_t*
+bsu_aclf_init (phy_t *phy, mac_config_t *mac_config, hal_timer_t *timer)
+{
+ bsu_aclf_t *ctx = &bsu_aclf_global;
+ dbg_assert (phy);
+ dbg_assert (mac_config);
+ memset (ctx, 0, sizeof (bsu_aclf_t));
+ ctx->phy = phy;
+ ctx->mac_config = mac_config;
+ ctx->hal_timer = timer;
+ hal_timer_instance_init (timer, &ctx->timer, ctx, bsu_aclf_timer_event);
+ return ctx;
+}
+
+void
+bsu_aclf_uninit (bsu_aclf_t *ctx)
+{
+ dbg_assert (ctx);
+}
+
void
bsu_aclf_compute_beacon_period_start_date (bsu_aclf_t *ctx, const u32 bts_ntb,
const s16 bto[HPAV_BEACON_BTO_NB],
@@ -128,68 +221,33 @@ bsu_aclf_compute_beacon_period_start_date (bsu_aclf_t *ctx, const u32 bts_ntb,
}
void
-bsu_aclf_shift_beacon_period_start_date (bsu_aclf_t *ctx)
+bsu_aclf_bto (bsu_aclf_t *ctx, s16 btos[], uint nb)
{
- uint i;
dbg_assert (ctx);
- u32 now = phy_date ();
- if (less_mod2p32 (ctx->bpsd[1], now))
- {
- for (i = 0; i < BSU_ACLF_BPSD_NB - 1; i++)
- ctx->bpsd[i] = ctx->bpsd[i+1];
- ctx->bpsd[i] += ctx->beacon_period;
- }
+ dbg_assert (btos);
+ dbg_assert (nb <= HPAV_BEACON_BTO_NB);
+ uint i;
+ for (i = 0; i < nb; i++)
+ btos[i] = ctx->bto[i];
}
void
-bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx)
+bsu_aclf_aclsc (bsu_aclf_t *ctx, bool aclsc)
{
dbg_assert (ctx);
- uint i;
- u32 now = phy_date ();
- u32 bts;
- int bto;
-
- bsu_aclf_compute_beacon_period_from_acl (ctx);
- /* First time the function is called. */
- if (ctx->bpsd[0] == ctx->bpsd[1])
- {
- ctx->bpsd[0] = now;
- for (i = 1; i < BSU_ACLF_BPSD_NB; i++)
- ctx->bpsd[i] = ctx->bpsd[i-1] + ctx->beacon_period;
- }
- /* Compute only if the current beacon period is over. */
- else if (lesseq_mod2p32 (ctx->bpsd[1], now)
- || (ctx->bpsd[0] == ctx->bpsd[1]))
- {
- /* Update the beacon period start time. */
- for (i = 0; i < BSU_ACLF_BPSD_NB - 1; i++)
- ctx->bpsd[i] = ctx->bpsd[i+1];
- /* Add on the last beacon period start date the beacon period
- * estimated. */
- ctx->bpsd[BSU_ACLF_BPSD_NB - 1] += ctx->beacon_period;
- }
- /* Compute the BTO using the theoretical beacon period value.
- * BTO is computed from bpsd[1]. */
- bts = ctx->bpsd[1];
- for (i = 0; i < HPAV_BEACON_BTO_NB; i++)
- {
- bto = ctx->bpsd[i+2] - bts - (i+1)*ctx->bp;
- /* Does bto overflowed ? */
- if (ABS(bto) >> 15 == 0)
- ctx->bto[i] = bto;
- else
- ctx->bto[i] = HPAV_BEACON_BTO_INVALID;
- }
+ ctx->aclsc = aclsc;
}
void
-bsu_aclf_bto (bsu_aclf_t *ctx, s16 btos[], uint nb)
+bsu_aclf_activate (bsu_aclf_t *ctx, bool status)
{
dbg_assert (ctx);
- dbg_assert (btos);
- dbg_assert (nb <= HPAV_BEACON_BTO_NB);
- uint i;
- for (i = 0; i < nb; i++)
- btos[i] = ctx->bto[i];
+ if (status)
+ {
+ bsu_aclf_acl_frequency_detection (ctx);
+ bsu_aclf_ac_compute_beacon_period_start_date (ctx);
+ hal_timer_instance_program (ctx->hal_timer, &ctx->timer, ctx->bpsd[1]);
+ }
+ else
+ hal_timer_instance_cancel (ctx->hal_timer, &ctx->timer);
}
diff --git a/cesar/bsu/aclf/test/utest/src/bpsd.c b/cesar/bsu/aclf/test/utest/src/bpsd.c
index 1ec9212f97..26dffb5fdc 100644
--- a/cesar/bsu/aclf/test/utest/src/bpsd.c
+++ b/cesar/bsu/aclf/test/utest/src/bpsd.c
@@ -20,6 +20,12 @@
#include "result_increase.h"
#include "result_decrease.h"
+void
+bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx);
+
+void
+bsu_aclf_shift_beacon_period_start_date (bsu_aclf_t *ctx);
+
static u32 zc_test [] = {0, 740000, 1480000};
static u32 zc_test_len = 3;
diff --git a/cesar/bsu/aclf/test/utest/src/common.c b/cesar/bsu/aclf/test/utest/src/common.c
index 66622f9557..a71115aaf4 100644
--- a/cesar/bsu/aclf/test/utest/src/common.c
+++ b/cesar/bsu/aclf/test/utest/src/common.c
@@ -24,8 +24,10 @@ bsu_aclf_test_init (bsu_aclf_test_t *t)
dbg_assert (t);
memset (t, 0, sizeof (bsu_aclf_test_t));
memset (&phy_test_global, 0, sizeof (bsu_aclf_test_phy_t));
- t->aclf = bsu_aclf_init ((phy_t *) &phy_test_global, &t->mac_config);
+ hal_timer_t *timer = hal_timer_init ();
+ t->aclf = bsu_aclf_init ((phy_t *) &phy_test_global, &t->mac_config, timer);
t->phy = &phy_test_global;
+ bsu_aclf_aclsc (t->aclf, true);
}
void
diff --git a/cesar/bsu/aclf/test/utest/src/freq.c b/cesar/bsu/aclf/test/utest/src/freq.c
index 679fac6235..37ae02654f 100644
--- a/cesar/bsu/aclf/test/utest/src/freq.c
+++ b/cesar/bsu/aclf/test/utest/src/freq.c
@@ -17,6 +17,9 @@
#include "bsu/aclf/test/utest/common.h"
void
+bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx);
+
+void
test_case_aclf_all_frequencies (test_t t)
{
test_case_begin (t, "All frequency possible");
diff --git a/cesar/bsu/aclf/test/utest/src/misc.c b/cesar/bsu/aclf/test/utest/src/misc.c
index 182b0ea77c..18ecd83849 100644
--- a/cesar/bsu/aclf/test/utest/src/misc.c
+++ b/cesar/bsu/aclf/test/utest/src/misc.c
@@ -17,6 +17,12 @@
#include "bsu/aclf/test/utest/common.h"
void
+bsu_aclf_shift_beacon_period_start_date (bsu_aclf_t *ctx);
+
+void
+bsu_aclf_timer_event (void *user_data);
+
+void
test_case_aclf__beacon_period (test_t test)
{
test_case_begin (test, "ACLF beacon period");
@@ -40,8 +46,53 @@ test_case_aclf__beacon_period (test_t test)
}
void
+test_case_aclf__timer (test_t test)
+{
+ bsu_aclf_test_t ctx;
+ uint i;
+ u32 bpsd[4];
+ bsu_aclf_test_init (&ctx);
+ test_case_begin (test, "Timer event");
+ test_begin (test, "ACL tracker")
+ {
+ bsu_aclf_activate (ctx.aclf, true);
+ bsu_aclf_beacon_period_start_date (ctx.aclf, bpsd, COUNT (bpsd));
+ /* Already in tracker mode. */
+ for (i = 0; i < COUNT (bpsd) - 1; i++)
+ test_fail_unless (bpsd[i+1] - bpsd[i]
+ == bsu_aclf_beacon_period (ctx.aclf));
+ u32 old = bpsd[0];
+ ctx.phy->phy = bpsd[1];
+ bsu_aclf_timer_event (ctx.aclf);
+ bsu_aclf_beacon_period_start_date (ctx.aclf, bpsd, COUNT (bpsd));
+ /* Already in tracker mode. */
+ for (i = 0; i < COUNT (bpsd) - 1; i++)
+ test_fail_unless (bpsd[i+1] - bpsd[i]
+ == bsu_aclf_beacon_period (ctx.aclf));
+ test_fail_unless (old + ctx.aclf->bp == bpsd[0]);
+ }
+ test_end;
+ test_begin (test, "Station behavior")
+ {
+ bsu_aclf_aclsc (ctx.aclf, false);
+ u32 old = bpsd[0];
+ ctx.phy->phy = bpsd[1];
+ bsu_aclf_timer_event (ctx.aclf);
+ bsu_aclf_beacon_period_start_date (ctx.aclf, bpsd, COUNT (bpsd));
+ /* Already in tracker mode. */
+ for (i = 0; i < COUNT (bpsd) - 1; i++)
+ test_fail_unless (bpsd[i+1] - bpsd[i]
+ == bsu_aclf_beacon_period (ctx.aclf));
+ test_fail_unless (old + ctx.aclf->bp == bpsd[0]);
+ }
+ test_end;
+ bsu_aclf_test_uninit (&ctx);
+}
+
+void
test_suite_aclf__misc (test_t test)
{
test_suite_begin (test, "Miscellaneous tests");
test_case_aclf__beacon_period (test);
+ test_case_aclf__timer (test);
}