summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNélio Laranjeiro2011-01-19 17:06:47 +0100
committerNélio Laranjeiro2011-02-01 13:38:30 +0100
commit907f71b7161e412e5b74623664251eb4a6c262dd (patch)
tree94690d766fb368c2a000c5633b9dd688f8a46df8
parentd69425fccc2c4e4c978b8f5c0acd347d002d6cf7 (diff)
bsu/aclf: better synchronization between the STA and the CCo, closes #2256
Supported frequencies: - 48.42Hz to 51.68Hz for 50Hz PowerLine (1000000 +/- BTO_MAX ticks). - 57.74Hz to 62.44Hz for 60Hz PowerLine (833333 +/- BTO_MAX ticks). Modifications: - BSU_ACLF_SET_FREQUENCY: - does not set the beacon period value. - set the maximum/minimum beacon period tick corresponding to the frequency found. - 6th beacon_period computed by the STA i.e. bpsd[6] += bpsd[5] - bpsd[4].
-rw-r--r--cesar/bsu/aclf/aclf.h36
-rw-r--r--cesar/bsu/aclf/src/aclf.c135
-rw-r--r--cesar/bsu/aclf/src/bpsd.c4
-rw-r--r--cesar/bsu/aclf/test/utest/Makefile26
-rw-r--r--cesar/bsu/aclf/test/utest/acl_period.sce12
-rw-r--r--cesar/bsu/aclf/test/utest/beacon_period.py255
-rw-r--r--cesar/bsu/aclf/test/utest/common.h38
-rw-r--r--cesar/bsu/aclf/test/utest/common.py12
-rw-r--r--cesar/bsu/aclf/test/utest/convertc.sce38
-rw-r--r--cesar/bsu/aclf/test/utest/estimateBP.sce41
-rw-r--r--cesar/bsu/aclf/test/utest/estimate_acl_freq_decrease.sce52
-rw-r--r--cesar/bsu/aclf/test/utest/estimate_acl_freq_increase.sce56
-rw-r--r--cesar/bsu/aclf/test/utest/estimate_acl_freq_stable.sce54
-rw-r--r--cesar/bsu/aclf/test/utest/phy.py61
-rw-r--r--cesar/bsu/aclf/test/utest/src/bpsd.c321
-rw-r--r--cesar/bsu/aclf/test/utest/src/common.c40
-rw-r--r--cesar/bsu/aclf/test/utest/src/freq.c150
-rw-r--r--cesar/bsu/aclf/test/utest/src/misc.c34
-rw-r--r--cesar/bsu/aclf/test/utest/zc_capture.sce18
-rw-r--r--cesar/bsu/aclf/test/utest/zc_capture_decrease.sce20
-rw-r--r--cesar/bsu/aclf/test/utest/zc_capture_increase.sce20
-rw-r--r--cesar/bsu/test/utest/src/bsut.c2
-rw-r--r--cesar/bsu/test/utest/src/schedules.c5
-rw-r--r--cesar/bsu/test/utest/src/tests.c40
-rw-r--r--cesar/bsu/test/utest/tests.h14
-rw-r--r--cesar/common/defs/homeplugAV.h2
-rw-r--r--cesar/common/tests/tests1
-rw-r--r--cesar/cp/av/cco/bw/src/bw.c3
28 files changed, 759 insertions, 731 deletions
diff --git a/cesar/bsu/aclf/aclf.h b/cesar/bsu/aclf/aclf.h
index f4a2df5294..19b873694d 100644
--- a/cesar/bsu/aclf/aclf.h
+++ b/cesar/bsu/aclf/aclf.h
@@ -41,14 +41,18 @@ enum bsu_aclf_bp_t
};
typedef enum bsu_aclf_bp_t bsu_aclf_bp_t;
-/** Zero cross values. */
-enum bsu_aclf_zc_t
-{
- BSU_ACLF_ZC_50HZ_TCK = (BSU_ACLF_BP_50HZ_TCK / 4),
- BSU_ACLF_ZC_55HZ_TCK = (BSU_ACLF_BP_55HZ_TCK / 4),
- BSU_ACLF_ZC_60HZ_TCK = (BSU_ACLF_BP_60HZ_TCK / 4)
-};
-typedef enum bsu_aclf_zc_t bsu_aclf_zc_t;
+/** The minimum value for the beacon period in ticks for 50Hz PowerLine. */
+#define BSU_ACLF_50HZ_CLK_MIN_TCK \
+ BSU_ACLF_BP_50HZ_TCK - BITS_ONES (HPAV_BEACON_BTO_VALID_BITS)
+/** The maximum value for the beacon period in ticks for 50Hz PowerLine. */
+#define BSU_ACLF_50HZ_CLK_MAX_TCK \
+ BSU_ACLF_BP_50HZ_TCK + BITS_ONES (HPAV_BEACON_BTO_VALID_BITS)
+/** The minimum value for the beacon period in ticks for 60Hz PowerLine. */
+#define BSU_ACLF_60HZ_CLK_MIN_TCK \
+ BSU_ACLF_BP_60HZ_TCK - BITS_ONES (HPAV_BEACON_BTO_VALID_BITS)
+/** The maximum value for the beacon period in ticks for 60Hz PowerLine. */
+#define BSU_ACLF_60HZ_CLK_MAX_TCK \
+ BSU_ACLF_BP_60HZ_TCK + BITS_ONES (HPAV_BEACON_BTO_VALID_BITS)
/** ACLF context structure. */
struct bsu_aclf_t
@@ -64,16 +68,10 @@ struct bsu_aclf_t
const bsu_aclf_frequency_t frequency;
/**
* Beacon period static value. This value never change it corresponds
- * to the value theoretical of the beacon period. (1 000 000 ticks
+ * to the theoretical value of the beacon period. (1 000 000 ticks
* for the 50 Hz and 833 333 ticks for the 60Hz)
*/
- const bsu_aclf_bp_t bp;
- /**
- * The zero cross theoretical value of the beacon period. Based on
- * the frequency detection. It corresponds to a quarter of the bp
- * value.
- */
- const bsu_aclf_zc_t zc;
+ const bsu_aclf_bp_t beacon_period_theo_tck;
/**
* Table of the beacon period start in date. The first value of the array
* is the beacon period start date of the current beacon period, the next
@@ -84,16 +82,16 @@ struct bsu_aclf_t
* Current beacon period value of the ACLF. Use to estimate the beacon
* period.
*/
- uint beacon_period;
+ uint beacon_period_tck;
/**
* The next four beacon period offset values. Those values can be set to
* invalid HPAV_BEACON_BTO_INVALID.
*/
s16 bto[HPAV_BEACON_BTO_NB];
/**
- * Last value read in PRATIC register.
+ * Last zero_cross read in PRATIC register.
*/
- u32 date;
+ u32 zero_cross_last_date;
/** Track the ACL. */
bool aclsc;
/** Hal timer context. */
diff --git a/cesar/bsu/aclf/src/aclf.c b/cesar/bsu/aclf/src/aclf.c
index 4816c043de..38f2a68490 100644
--- a/cesar/bsu/aclf/src/aclf.c
+++ b/cesar/bsu/aclf/src/aclf.c
@@ -22,9 +22,8 @@
do { \
*((bsu_aclf_frequency_t*) &ctx->frequency) \
= BSU_ACLF_FREQ_ ## freq ## HZ; \
- *((bsu_aclf_bp_t*) &ctx->bp) = BSU_ACLF_BP_ ## freq ## HZ_TCK; \
- *((uint*) &ctx->zc) = BSU_ACLF_ZC_ ## freq ## HZ_TCK; \
- ctx->beacon_period = ctx->bp; \
+ *((bsu_aclf_bp_t*) &ctx->beacon_period_theo_tck) \
+ = BSU_ACLF_BP_ ## freq ## HZ_TCK; \
} while (0)
/** WP History coefficient value. */
@@ -34,25 +33,57 @@
static bsu_aclf_t bsu_aclf_global;
/**
+ * Truncate the beacon period ticks computed to be suitable for BTOs.
+ * \param ctx the module context.
+ *
+ * The objective is to provide a BTO with the correct value allowing the STA
+ * to synchronise correctly.
+ * Norm EN50160 inform that the 50Hz PowerLine may have some variation on the
+ * frequency reaching +/- 15% for non interconnected PowerLine system.
+ * This means that the 50Hz PowerLine frequency have a range value from 42.5Hz
+ * to 57.5Hz. BTOs only allow a range from 48.42Hz to 51.68Hz.
+ * This function will do the same for both frequencies i.e. 50 and 60Hz.
+ */
+static void
+bsu_aclf_truncate_beacon_period (bsu_aclf_t *ctx)
+{
+ uint clk_min_tck =
+ ctx->beacon_period_theo_tck
+ - BITS_ONES (HPAV_BEACON_BTO_VALID_BITS);
+ uint clk_max_tck =
+ ctx->beacon_period_theo_tck
+ + BITS_ONES (HPAV_BEACON_BTO_VALID_BITS);
+ /* Special cases for cable mode. */
+ if (ctx->beacon_period_tck == 0)
+ ctx->beacon_period_tck = BSU_ACLF_BP_50HZ_TCK;
+ else if (ctx->beacon_period_tck > clk_max_tck)
+ ctx->beacon_period_tck = clk_max_tck;
+ else if (ctx->beacon_period_tck < clk_min_tck)
+ ctx->beacon_period_tck = clk_min_tck;
+}
+
+/**
* Compute the beacon period duration from the AC Line frequency variation.
* \param ctx the module context.
*/
-static inline void
+static void
bsu_aclf_compute_beacon_period_from_acl (bsu_aclf_t *ctx)
{
- u32 newzc, diff;
- dbg_assert (ctx);
- newzc = phy_clock_get_zero_cross_captured_date (ctx->phy);
- diff = (newzc - ctx->date) % (ctx->bp + 10000);
- ctx->date = newzc;
- if (diff <= 3 * ctx->zc)
+ uint zc_interval_tck = ctx->beacon_period_tck / 2;
+ u32 zero_cross_date = phy_clock_get_zero_cross_captured_date (ctx->phy);
+ u32 zc_diff_tck = zero_cross_date - ctx->zero_cross_last_date;
+ if (zc_diff_tck)
{
- float div;
- div = ((float)diff / (float)ctx->zc);
- diff = (4 - div) * ctx->zc + diff;
+ /* Compute the number of zero cross since the last read value. */
+ uint zc_nb =
+ (zc_diff_tck + zc_interval_tck / 2) / zc_interval_tck;
+ uint bp_tck = 2 * zc_diff_tck / zc_nb;
+ ctx->beacon_period_tck +=
+ BSU_ACLF_WP * ((int)bp_tck - (int)ctx->beacon_period_tck);
+ bsu_aclf_truncate_beacon_period (ctx);
+ /* Store the last zero crossing date. */
+ ctx->zero_cross_last_date = zero_cross_date;
}
- /* Using a Wp value with k = 4. */
- ctx->beacon_period += BSU_ACLF_WP * ((s32) diff - (s32)ctx->beacon_period);
}
/**
@@ -72,8 +103,12 @@ bsu_aclf_shift_beacon_period_start_date (bsu_aclf_t *ctx)
{
for (i = 0; i < BSU_ACLF_BPSD_NB - 1; i++)
ctx->bpsd[i] = ctx->bpsd[i+1];
- ctx->bpsd[i] += ctx->bp;
- ctx->beacon_period = ctx->bpsd[1] - ctx->bpsd[0];
+ /* For the last beacon period start date, add the difference of the
+ * previous one, this should help the station to keep a
+ * synchronisation near the CCo's clock even if it miss 5 beacons. */
+ ctx->bpsd[BSU_ACLF_BPSD_NB - 1] +=
+ ctx->bpsd[BSU_ACLF_BPSD_NB - 2] - ctx->bpsd[BSU_ACLF_BPSD_NB - 3];
+ ctx->beacon_period_tck = ctx->bpsd[1] - ctx->bpsd[0];
}
}
@@ -97,7 +132,7 @@ bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx)
{
ctx->bpsd[0] = now;
for (i = 1; i < BSU_ACLF_BPSD_NB; i++)
- ctx->bpsd[i] = ctx->bpsd[i-1] + ctx->beacon_period;
+ ctx->bpsd[i] = ctx->bpsd[i-1] + ctx->beacon_period_tck;
}
/* Compute only if the current beacon period is over. */
else if (lesseq_mod2p32 (ctx->bpsd[1], now))
@@ -107,14 +142,14 @@ bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx)
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;
+ ctx->bpsd[BSU_ACLF_BPSD_NB - 1] += ctx->beacon_period_tck;
}
/* 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] - ctx->bpsd[i+1] - ctx->bp;
+ bto = ctx->bpsd[i+2] - ctx->bpsd[i+1] - ctx->beacon_period_theo_tck;
/* Does bto overflowed ? */
if (ABS(bto) >> 15 == 0)
ctx->bto[i] = bto;
@@ -151,32 +186,36 @@ bsu_aclf_timer_event (void *user_data)
void
bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx)
{
- u32 wait_date, newzc = 0, diff = 0;
- dbg_assert (ctx);
- dbg_assert (ctx->phy);
- /* Compute the date until the one it should wait the new zc. It waits a
- * little bit more than a 50Hz zero cross. */
- wait_date = phy_date () + BSU_ACLF_ZC_50HZ_TCK + 1000;
- /* Special behavior for some unit tests and maximus. */
+ uint diff_zc_tck;
u32 now = phy_date ();
- if (now != phy_date ())
+ u32 zero_cross_new_date, zero_cross_date, wait_until_date;
+ /* Get the last zero cross date from hardware. */
+ zero_cross_date = zero_cross_new_date =
+ phy_clock_get_zero_cross_captured_date (ctx->phy);
+ /* Protection for maximus. */
+ if (less_mod2p32 (now, phy_date ()))
{
- /* Wait actively on Zero Cross change for 250 000 ticks. */
- for (newzc = ctx->date =
- phy_clock_get_zero_cross_captured_date (ctx->phy);
- less_mod2p32 (phy_date (), wait_date)
- && newzc == ctx->date;
- newzc = phy_clock_get_zero_cross_captured_date (ctx->phy))
- ;
- /* compute the difference between the two zc. */
- diff = newzc - ctx->date;
+ /* Catch the first zero cross.
+ * If the frequency does not change the expiration should stop
+ * the loop. */
+ wait_until_date = phy_date () + MAC_MS_TO_TCK (50);
+ while (lesseq_mod2p32 (phy_date (), wait_until_date)
+ && zero_cross_new_date == zero_cross_date)
+ zero_cross_new_date =
+ phy_clock_get_zero_cross_captured_date (ctx->phy);
}
- if (diff == 0 || diff >= BSU_ACLF_ZC_55HZ_TCK)
+ /* Compute the beacon period from the zero crossing.
+ * Beacon period is twice the zero crossing. Zero crossing is only
+ * store by hardware on a rising edge of the PowerLine cycle.*/
+ diff_zc_tck = zero_cross_new_date - zero_cross_date;
+ ctx->beacon_period_tck = 2 * diff_zc_tck;
+ if (diff_zc_tck == 0
+ || ctx->beacon_period_tck >= BSU_ACLF_BP_55HZ_TCK)
BSU_ACLF_SET_FREQUENCY (50);
else
BSU_ACLF_SET_FREQUENCY (60);
- ctx->beacon_period = ctx->bp;
- ctx->date = newzc;
+ ctx->zero_cross_last_date = zero_cross_new_date;
+ bsu_aclf_truncate_beacon_period (ctx);
}
/**
@@ -189,10 +228,10 @@ bsu_aclf_clear (bsu_aclf_t *ctx)
uint i;
for (i = 0; i < COUNT (ctx->bpsd); i++)
ctx->bpsd[i] = 0;
- ctx->beacon_period = ctx->bp;
+ ctx->beacon_period_tck = ctx->beacon_period_theo_tck;
for (i = 0; i < COUNT (ctx->bto); i++)
ctx->bto[i] = 0;
- ctx->date = 0;
+ ctx->zero_cross_last_date = 0;
ctx->aclsc = false;
}
@@ -233,15 +272,17 @@ bsu_aclf_compute_beacon_period_start_date (bsu_aclf_t *ctx, const u32 bts_ntb,
ctx->bto[i] = bto[i];
/* BTO is valid use it to compute. */
if (bto[i] != HPAV_BEACON_BTO_INVALID)
- ctx->bpsd[i+1] = ctx->bpsd[i] + ctx->bp + bto[i];
- /* BTO is not valid, STA assumes the beacon period start date has
- * no offset (FIXME: Good idea ?) */
+ ctx->bpsd[i+1] =
+ ctx->bpsd[i] + ctx->beacon_period_theo_tck + bto[i];
+ /* BTO is not valid, take the difference from the previous beacon
+ * period. */
else
- ctx->bpsd[i+1] = ctx->bpsd[i] + ctx->bp;
+ ctx->bpsd[i+1] += ctx->bpsd[i] - ctx->bpsd[i-1];
}
else
- ctx->bpsd[i+1] = ctx->bpsd[i] + ctx->bp;
+ ctx->bpsd[i+1] += ctx->bpsd[i] - ctx->bpsd[i-1];
}
+ ctx->beacon_period_tck = ctx->bpsd[1] - ctx->bpsd[0];
}
void
diff --git a/cesar/bsu/aclf/src/bpsd.c b/cesar/bsu/aclf/src/bpsd.c
index 273bf58c74..14080e1ea7 100644
--- a/cesar/bsu/aclf/src/bpsd.c
+++ b/cesar/bsu/aclf/src/bpsd.c
@@ -39,12 +39,12 @@ u32
bsu_aclf_beacon_period_tck (bsu_aclf_t *ctx)
{
dbg_assert (ctx);
- return ctx->bpsd[1] - ctx->bpsd[0];
+ return ctx->beacon_period_tck;
}
u32
bsu_aclf_beacon_period_atu (bsu_aclf_t *ctx)
{
dbg_assert (ctx);
- return MAC_TCK_TO_ATU (ctx->bpsd[1] - ctx->bpsd[0]);
+ return MAC_TCK_TO_ATU (ctx->beacon_period_tck);
}
diff --git a/cesar/bsu/aclf/test/utest/Makefile b/cesar/bsu/aclf/test/utest/Makefile
index 1121f2b3e4..5c001c43ee 100644
--- a/cesar/bsu/aclf/test/utest/Makefile
+++ b/cesar/bsu/aclf/test/utest/Makefile
@@ -5,29 +5,3 @@ aclf_SOURCES = aclf.c common.c bpsd.c freq.c misc.c
aclf_MODULES = lib bsu/aclf hal/timer/stub
include $(BASE)/common/make/top.mk
-
-increase_files = $(OBJ_DIR)/inc/table_increase.h \
- $(OBJ_DIR)/inc/result_increase.h \
- $(OBJ_DIR)/result_increase.csv
-decrease_files = $(OBJ_DIR)/inc/table_decrease.h \
- $(OBJ_DIR)/inc/result_decrease.h \
- $(OBJ_DIR)/result_decrease.csv
-stable_files = $(OBJ_DIR)/inc/table_stable.h \
- $(OBJ_DIR)/inc/result_stable.h \
- $(OBJ_DIR)/result_stable.csv
-acl_files = $(OBJ_DIR)/inc/zc_cross.h
-SCILAB_FILE = $(increase_files) $(decrease_files) $(stable_files) $(acl_files)
-CLEAN_FILES += $(SCILAB_FILE)
-
-$(call src2obj,src/bpsd.c,host): $(increase_files) $(decrease_files) \
- $(stable_files)
-$(call src2obj,src/common.c,host): $(acl_files)
-
-$(increase_files): estimate_acl_freq_increase.sce
- scilab -nw -f $<
-$(decrease_files): estimate_acl_freq_decrease.sce
- scilab -nw -f $<
-$(stable_files): estimate_acl_freq_stable.sce
- scilab -nw -f $<
-$(acl_files): acl_period.sce
- scilab -nw -f $<
diff --git a/cesar/bsu/aclf/test/utest/acl_period.sce b/cesar/bsu/aclf/test/utest/acl_period.sce
deleted file mode 100644
index be612419ad..0000000000
--- a/cesar/bsu/aclf/test/utest/acl_period.sce
+++ /dev/null
@@ -1,12 +0,0 @@
-// C array writer
-getf('convertc.sce');
-
-frequency = [40:1:80];
-acl_period = 1 ./ frequency;
-bp_period_tck = 2 .* acl_period ./ 40e-9;
-zc_tck = bp_period_tck ./ 4
-
-// Write the result.
-convertc_array ('obj/inc/zc_cross.h', 'zero_cross', zc_tck);
-
-exit;
diff --git a/cesar/bsu/aclf/test/utest/beacon_period.py b/cesar/bsu/aclf/test/utest/beacon_period.py
new file mode 100644
index 0000000000..238072439c
--- /dev/null
+++ b/cesar/bsu/aclf/test/utest/beacon_period.py
@@ -0,0 +1,255 @@
+#!/usr/bin/python
+
+#############################################################################
+# Copyright (C) 2011 Spidcom
+#
+# This script simulates a PowerLine frequency change.
+#
+# Frequency in Europe can go from 42.5Hz to 57.5Hz.
+# In US it can go from 51 to 69Hz.
+# To keep a good synchronisation and BTO computation value,
+# under 55Hz, 50Hz should be chose, 60Hz when frequency is greater.
+#
+# HomePlug AV only supports a small range of variation on the PowerLine which
+# is provided by the BTOs with the central beacon. Those BTOs are a signed
+# 16bits values with 0x8000 reserved for invalid value.
+# The station computes the next beacon periods from the BTS and the BTOs with
+# the following formulae.
+# bpsd_n = bpsd_{n-1} + beacon_period_theoretical_tck + bto_n
+# bpsd_n is the next beacon period start date.
+# beacon_period_theoretical is the beacon period in ticks corresponding to 50
+# or 60Hz.
+# Knowing this the station is only able to synchronise if the variation is in
+# a small range i.e beacon_period_theoretical_tck +/- 0x7fff.
+#
+# For 50Hz the maximum delta 1.0e6 +/- 32567, so 48.42Hz to 51.68Hz.
+# For 60Hz the maximum delta 833333 +/- 32567, so 57.74Hz to 62.44Hz.
+#
+#############################################################################
+
+import sys
+from phy import Phy
+from common import MAC_MS_TO_TCK
+
+CLOCK_50HZ_TCK = 1000000
+CLOCK_55HZ_TCK = 909090
+CLOCK_60HZ_TCK = 833333
+
+CLOCK_50HZ_MIN_TCK = CLOCK_50HZ_TCK - 0x7fff
+CLOCK_50HZ_MAX_TCK = CLOCK_50HZ_TCK + 0x7fff
+
+CLOCK_60HZ_MIN_TCK = CLOCK_60HZ_TCK - 0x7fff
+CLOCK_60HZ_MAX_TCK = CLOCK_60HZ_TCK + 0x7fff
+
+class BsuAclf:
+ """Python BSU ACLF class."""
+
+ def __init__ (self, phy):
+ """Initialise the class."""
+ self.phy = phy
+ self.frequency_theo_hz = 0
+ self.beacon_period_theo_tck = 0
+ self.beacon_period_tck = 0
+ self.zero_cross_last_read_date = 0
+
+ def __beacon_period_fit_bto_range (self):
+ """Truncate value to have a beacon period which can fit in the BTO
+ range value."""
+ if self.beacon_period_tck > self.beacon_period_theo_tck + 0x7fff:
+ self.beacon_period_tck = self.beacon_period_theo_tck + 0x7fff
+ elif self.beacon_period_tck < self.beacon_period_theo_tck - 0x7fff:
+ self.beacon_period_tck = self.beacon_period_theo_tck - 0x7fff
+
+ def frequency_detection (self):
+ """Try to find at what frequency the medium is at.
+ phy: phy class initialised.
+ """
+ zero_cross_tck = self.phy.zero_crossing ()
+ zero_cross_new_tck = zero_cross_tck
+ now = self.phy.date ()
+ wait_until = now + MAC_MS_TO_TCK (50)
+ while self.phy.date () < wait_until \
+ and zero_cross_new_tck == zero_cross_tck:
+ zero_cross_new_tck = self.phy.zero_crossing ()
+ # this line should not be implemented in C.
+ self.phy.clock (1000)
+ diff_zc_tck = zero_cross_new_tck - zero_cross_tck
+ self.beacon_period_tck = 2 * diff_zc_tck
+ if self.beacon_period_tck >= CLOCK_55HZ_TCK \
+ or diff_zc_tck == 0:
+ self.frequency_theo_hz = 50
+ self.beacon_period_theo_tck = CLOCK_50HZ_TCK
+ self.zero_cross_last_read_date = zero_cross_new_tck
+ self.__beacon_period_fit_bto_range ()
+ return self.frequency_theo_hz
+ else:
+ self.frequency_theo_hz = 60
+ self.beacon_period_theo_tck = CLOCK_60HZ_TCK
+ self.zero_cross_last_read_date = zero_cross_new_tck
+ self.__beacon_period_fit_bto_range ()
+ return self.frequency_theo_hz
+
+ def compute_beacon_period (self):
+ """Compute the beacon period using the phy class."""
+ zc_interval_tck = self.beacon_period_tck / 2
+ zero_cross_date = self.phy.zero_crossing ()
+ zc_diff_tck = zero_cross_date - self.zero_cross_last_read_date
+ if zc_diff_tck:
+ zc_nb = (zc_diff_tck + zc_interval_tck / 2) \
+ / zc_interval_tck
+ bp_tck = 2 * zc_diff_tck / zc_nb
+ self.zero_cross_last_read_date = zero_cross_date
+ self.beacon_period_tck += \
+ int (0.0625 * (bp_tck - self.beacon_period_tck))
+ self.__beacon_period_fit_bto_range ()
+ return self.beacon_period_tck
+
+if __name__ == '__main__':
+ import unittest
+
+ class TestBeaconPeriod(unittest.TestCase):
+ def setUp (self):
+ pass
+ def tearDown (self):
+ pass
+
+ def verify_beacon_period (self, bsuaclf, frequency):
+ """Verify the beacon period estimated is correct.
+ """
+ # powerline_cycle_tck = 25.0e6 * 1/F = 25.0e6 / F
+ # beacon_period_tck = 2 * powerline_cycle_tck
+ diff = int (50.0e6 / frequency) - bsuaclf.beacon_period_tck
+ if bsuaclf.frequency_theo_hz == 50:
+ self.failUnless (\
+ bsuaclf.beacon_period_tck == CLOCK_50HZ_MIN_TCK \
+ or bsuaclf.beacon_period_tck == CLOCK_50HZ_MAX_TCK \
+ or (diff >= -25 and diff <= 25) \
+ )
+ else:
+ self.failUnless (\
+ bsuaclf.beacon_period_tck == CLOCK_60HZ_MIN_TCK \
+ or bsuaclf.beacon_period_tck == CLOCK_60HZ_MAX_TCK \
+ or (diff >= -25 and diff <= 25) \
+ )
+
+ def test_frequency_detection (self):
+ """test the frequency detection for from 42.5 to 69Hz.
+ Result expected is a detected medium frequency at:
+ - 50Hz for frequency from 42.5 to 54.2Hz.
+ - 60Hz for frequency from 54.3 to 69Hz.
+ """
+ # Xrange does not support floating points, so frequencies to tests
+ # are multiplied by 10.
+ for f in xrange (425, 690):
+ frequency = (f + 0.0) / 10
+ p = Phy (frequency)
+ ba = BsuAclf (p)
+ res = ba.frequency_detection ()
+ self.failUnless ((frequency <= 55.0 and res == 50)
+ or (frequency > 55 and res == 60))
+ self.verify_beacon_period (ba, frequency)
+
+ def test_estimate_beacon_period (self):
+ """Test the algorithm for beacon period estimation.
+ Should test the beacon period computation for each possible
+ frequency. The beacon period is not just twice the period of the
+ powerline, it is smoothed with the previous beacon period and the
+ one computed using two powerline zero cross.
+ """
+ for f in xrange (425, 690):
+ frequency = (f + 0.0) / 10
+ p = Phy (frequency)
+ ba = BsuAclf (p)
+ ba.frequency_detection ()
+ # current beacon period.
+ for i in xrange (0, 10):
+ # Give some clocks ticks.
+ p.clock (ba.beacon_period_tck)
+ ba.compute_beacon_period ()
+ self.verify_beacon_period (ba, frequency)
+
+ def frequency_variation (self, freq, step = 0.1, inc = True):
+ """Make the frequency increase or decrease during the test.
+ freq: Initial frequency (float value) [42.5, 69].
+ step: Increase or decrease step (float value).
+ inc: True to increase frequency, false otherwise.
+ """
+ p = Phy (freq)
+ ba = BsuAclf (p)
+ ba.frequency_detection ()
+ if inc:
+ while ((p.frequency () <= 69.0
+ and ba.frequency_theo_hz == 60)
+ or (p.frequency () <= 57.5
+ and ba.frequency_theo_hz == 50)):
+ for i in xrange (0, 100):
+ # give some clocks ticks.
+ p.clock (ba.beacon_period_tck)
+ ba.compute_beacon_period ()
+ self.verify_beacon_period (ba, p.frequency ())
+ p.frequency_inc (step)
+ else:
+ while ((p.frequency () >= 42.5
+ and ba.frequency_theo_hz == 50)
+ or (p.frequency () >= 51.0
+ and ba.frequency_theo_hz == 60)):
+ for i in xrange (0, 100):
+ # give some clocks ticks.
+ p.clock (ba.beacon_period_tck)
+ ba.compute_beacon_period ()
+ self.verify_beacon_period (ba, p.frequency ())
+ p.frequency_dec (step)
+
+ def test_estimate_beacon_period_frequency_increase (self):
+ """Test the beacon period computation with a frequency which
+ increase by 0.1 Hz each 100 beacon periods.
+ """
+ self.frequency_variation (42.5)
+ self.frequency_variation (57.0)
+
+ def test_estimate_beacon_period_frequency_deacrease (self):
+ """Test the beacon period computation with a frequency which
+ decrease by 0.1 Hz each 100 beacon periods.
+ """
+ self.frequency_variation (69, inc = False)
+ self.frequency_variation (55.0, inc = False)
+
+ def estimate_beacon_period_frequency_inc_and_dec (self, freq,
+ step = 0.1):
+ p = Phy (freq)
+ ba = BsuAclf (p)
+ ba.frequency_detection ()
+ while ((p.frequency () <= 69.0
+ and ba.frequency_theo_hz == 60)
+ or (p.frequency () <= 57.5
+ and ba.frequency_theo_hz == 50)):
+ for i in xrange (0, 100):
+ # give some clocks ticks.
+ p.clock (ba.beacon_period_tck)
+ beacon_period_tck = ba.compute_beacon_period ()
+ self.verify_beacon_period (ba, p.frequency ())
+ p.frequency_inc (0.1)
+ while ((p.frequency () >= 42.5
+ and ba.frequency_theo_hz == 50)
+ or (p.frequency () >= 51.0
+ and ba.frequency_theo_hz == 60)):
+ for i in xrange (0, 100):
+ # give some clocks ticks.
+ p.clock (ba.beacon_period_tck)
+ beacon_period_tck = ba.compute_beacon_period ()
+ self.verify_beacon_period (ba, p.frequency ())
+ p.frequency_dec (0.1)
+
+ def test_estimate_beacon_period_frequency_inc_and_dec (self):
+ """Test the beacon period computation with a frequency which
+ increase by 0.1 Hz each 100 beacon periods. It will restart just
+ after with a decrease of 0.1 Hz each 100 beacons.
+ """
+ self.estimate_beacon_period_frequency_inc_and_dec (42.5)
+ self.estimate_beacon_period_frequency_inc_and_dec (55.1)
+
+ # Start the unit test.
+ suite = unittest.TestLoader().loadTestsFromTestCase(TestBeaconPeriod)
+ testResult = unittest.TextTestRunner(verbosity=2).run(suite)
+# For nightly build errors
+sys.exit ((1, 0)[testResult.wasSuccessful ()])
diff --git a/cesar/bsu/aclf/test/utest/common.h b/cesar/bsu/aclf/test/utest/common.h
index d1f8a27c82..10e360fe61 100644
--- a/cesar/bsu/aclf/test/utest/common.h
+++ b/cesar/bsu/aclf/test/utest/common.h
@@ -9,34 +9,22 @@
* }}} */
/**
* \file bsu/aclf/test/utest/src/common.c
- * \brief Common functions for ACLF tests.
+ * \brief Common functions for ACLF tests.
* \ingroup bsu_aclf
*/
#include "bsu/aclf/aclf.h"
-enum bsu_aclf_test_aclf_phy_t
-{
- BSU_ACLF_TEST_ACLF_PHY_NONE,
- BSU_ACLF_TEST_ACLF_PHY_AC_STABLE,
- BSU_ACLF_TEST_ACLF_PHY_AC_INC,
- BSU_ACLF_TEST_ACLF_PHY_AC_DEC,
- BSU_ACLF_TEST_ACLF_PHY_AC_CABLE
-};
-
struct bsu_aclf_test_phy_t
{
/** Frequency simulation. */
- uint frequency;
- /** Phy simulation context. */
- u32 phy;
- /** Zero cross value. */
- u32 zc_cross_index;
- /** Last Zero Cross simulated. */
- u32 zc;
- /** ACL type. */
- enum bsu_aclf_test_aclf_phy_t phy_type;
- /** Table index for some tests. */
- uint table_index;
+ float frequency_hz;
+ /** Phy date. */
+ u32 phy_date;
+ /** Zero crossing. */
+ u32 zero_crossing_date;
+ /** False to use phy clock function to make time goes on,
+ * or false to increase time by 1000 ticks on phy_date function call. */
+ bool use_phy_clock;
};
typedef struct bsu_aclf_test_phy_t bsu_aclf_test_phy_t;
@@ -67,6 +55,14 @@ bsu_aclf_test_init (bsu_aclf_test_t *t);
void
bsu_aclf_test_uninit (bsu_aclf_test_t *t);
+/**
+ * Function to pilot clock and zero crossing.
+ * \param ctx the test phy context.
+ * \param ticks the value to increase the phy_date with.
+ */
+void
+phy_clock (bsu_aclf_test_phy_t *ctx, u32 ticks);
+
END_DECLS
#endif /* bsu_aclf_test_utest_common_h */
diff --git a/cesar/bsu/aclf/test/utest/common.py b/cesar/bsu/aclf/test/utest/common.py
new file mode 100644
index 0000000000..0cb0c607cb
--- /dev/null
+++ b/cesar/bsu/aclf/test/utest/common.py
@@ -0,0 +1,12 @@
+#!/usr/bin/python
+
+#############################################################################
+# Copyright (C) 2011 Spidcom
+#
+# Common function to unit tests.
+#############################################################################
+
+def MAC_MS_TO_TCK(ms):
+ """Convert a ms time into tcks."""
+ MAC_TCK_PER_US = 25
+ return int ((ms) * MAC_TCK_PER_US * 1000)
diff --git a/cesar/bsu/aclf/test/utest/convertc.sce b/cesar/bsu/aclf/test/utest/convertc.sce
deleted file mode 100644
index fa744b1ec6..0000000000
--- a/cesar/bsu/aclf/test/utest/convertc.sce
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPiDCOM Technologies.
-// Nélio Laranjeiro
-// 16-05-2008
-// Cesar project.
-
-// Convert an array of values to a C array.
-
-// @param file_name the file name to write the data in. The file shall be a
-// c file.
-// @param array_name the array name.
-// @param array the array to write.
-function convertc_array (file_name, array_name, array)
-
-nb_points = length(array);
-
-define_name = file_name + "_" + array_name;
-define_name = strsubst (define_name, ".", "_")
-define_name = strsubst (define_name, "/", "_")
-
-// Provide an array for the C unit test.
-result_file = file ('open', file_name, 'unknown');
- fprintf (result_file, "#ifndef %s", define_name);
- fprintf (result_file, "#define %s", define_name);
- fprintf (result_file, "/* File generated by scilab */");
- fprintf (result_file, "");
- fprintf (result_file, "uint %s [%d] = {", array_name, nb_points);
- for i = 1:nb_points - 1
- fprintf (result_file, " %d, ", array(i));
- end
-
-// Write the last value.
-fprintf (result_file, "%d };", array(nb_points));
-fprintf (result_file, "uint %s = %d;", array_name + '_length', nb_points);
-
-fprintf (result_file, "#endif /* %s */", define_name);
-file ('close', result_file);
-
-endfunction
diff --git a/cesar/bsu/aclf/test/utest/estimateBP.sce b/cesar/bsu/aclf/test/utest/estimateBP.sce
deleted file mode 100644
index 3fe548737d..0000000000
--- a/cesar/bsu/aclf/test/utest/estimateBP.sce
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPiDCOM Technologies.
-// Nélio Laranjeiro
-// 16-05-2008
-// Cesar project.
-
-//Estimate the beacon period using the synchronisation of the PWL.
-//This shall use a function to generate the ACL frequency.
-
-// The function phy_clock_get_zero_cross_captured_date shall be written in
-// function of the test which is being done.
-// WARN : Import the file containing the function before using this script.
-
-// compute the estimation of the ACL period.
-// @param cp the CP context.
-// - date_ntb[2]
-// - bp_ntb
-// - zc_ntb
-// - per_ntb
-// @return the [per, date_ntb']
-function [res] = estimate_beacon_period (cp)
-
-date_ntb = [cp(1) ,cp(2)];
-bp_ntb = cp(3);
-zc_ntb = cp(4);
-per_ntb = cp(5);
-
-date_ntb(2) = date_ntb(1);
-date_ntb(1) = phy_clock_get_zero_cross (date_ntb(2));
-diff_ntb = modulo((date_ntb(1) - date_ntb(2)), bp_ntb + 10000);
-
-if diff_ntb < 3*zc_ntb
- diff_ntb = (4-int((diff_ntb / zc_ntb))) * zc_ntb + diff_ntb;
-end
-
-// Using a WP with a K = 4.
-per_ntb = int(per_ntb + 0.0625 * (diff_ntb - per_ntb));
-
-res = [date_ntb, bp_ntb, zc_ntb, per_ntb];
-return res;
-
-endfunction
diff --git a/cesar/bsu/aclf/test/utest/estimate_acl_freq_decrease.sce b/cesar/bsu/aclf/test/utest/estimate_acl_freq_decrease.sce
deleted file mode 100644
index 773a386af2..0000000000
--- a/cesar/bsu/aclf/test/utest/estimate_acl_freq_decrease.sce
+++ /dev/null
@@ -1,52 +0,0 @@
-// SPiDCOM Technologies.
-// Nélio Laranjeiro
-// 16-05-2008
-// Cesar project.
-
-// Launch a test to verify the estimation function.
-
-// load the file, containing the function to generate a stable 50hz zero
-// cross.
-getf ('zc_capture_decrease.sce');
-getf ('estimateBP.sce');
-
-// C array writer
-getf('convertc.sce');
-
-// Initialise the environment.
-date_ntb = zeros(1,2);
-// 50 Hz in ticks.
-bp_ntb = 1e6;
-zc_ntb = bp_ntb / 4;
-
-nb_points = 1e3;
-
-cp = [date_ntb, bp_ntb, zc_ntb, bp_ntb];
-
-//Vector of points.
-result = zeros(nb_points,length(cp) + 1);
-for i = 1:1000
- cp = estimate_beacon_period (cp);
-
- result (i,:) = [cp, cp(1) - cp(2)];
- bp_ntb = cp(3) + 1e6;
-end
-
-// Write the result in a file.
-result_file = file('open', 'obj/result_decrease.csv', 'unknown');
-fprintf (result_file, "Per, Per(ATU), Zc 1, Zc 2, Diff\n");
-for i = 1:nb_points
- fprintf (result_file, "%d, %d, %d, %d, %d\n", result(i,5), int(result(i,5) / 256), result(i,1), result(i,2), result(i,6));
-end
-// Close the file.
-file('close', result_file);
-
-// Write the array.
-res = result(:,1);
-convertc_array ('obj/inc/table_decrease.h', 'ac_decrease', res);
-
-// Write the result of the simulation.
-res = result (:,5);
-convertc_array ('obj/inc/result_decrease.h', 'result_ac_decrease', res);
-
-exit;
diff --git a/cesar/bsu/aclf/test/utest/estimate_acl_freq_increase.sce b/cesar/bsu/aclf/test/utest/estimate_acl_freq_increase.sce
deleted file mode 100644
index 8d8553568e..0000000000
--- a/cesar/bsu/aclf/test/utest/estimate_acl_freq_increase.sce
+++ /dev/null
@@ -1,56 +0,0 @@
-// SPiDCOM Technologies.
-// Nélio Laranjeiro
-// 16-05-2008
-// Cesar project.
-
-// Launch a test to verify the estimation function.
-
-// load the file, containing the function to generate a stable 50hz zero
-// cross.
-getf ('zc_capture_increase.sce');
-getf ('estimateBP.sce');
-
-// C array writer
-getf('convertc.sce');
-
-// Initialise the environment.
-date_ntb = zeros (1,2);
-// 50 Hz in ticks.
-bp_ntb = 1e6;
-zc_ntb = bp_ntb / 4;
-
-// Number of points.
-nb_points = 1000;
-
-
-cp = [date_ntb, bp_ntb, zc_ntb, bp_ntb];
-
-//Vector of points.
-result = zeros(nb_points,length(cp) + 1);
-
-for i = 1:nb_points
- cp = estimate_beacon_period (cp);
-
- result (i,:) = [cp, cp(1) - cp(2)];
- bp_ntb = cp(3) + 1e6;
-end
-
-// Write the result in a file.
-result_file = file('open', 'obj/result_increase.csv', 'unknown');
-
-fprintf (result_file, "Per, Per(ATU), Zc 1, Zc 2, diff\n");
-for i = 1:nb_points
- fprintf (result_file, "%d, %d, %d, %d, %d\n", result(i,5), int(result(i,5) / 256), result(i,1), result(i,2), result(i,6));
-end
-// Close the file.
-file('close', result_file);
-
-// Write the array.
-res = result(:,1);
-convertc_array ('obj/inc/table_increase.h', 'ac_increase', res);
-
-// Write the result of the simulation.
-res = result (:,5);
-convertc_array ('obj/inc/result_increase.h', 'result_ac_increase', res);
-
-exit;
diff --git a/cesar/bsu/aclf/test/utest/estimate_acl_freq_stable.sce b/cesar/bsu/aclf/test/utest/estimate_acl_freq_stable.sce
deleted file mode 100644
index ea18bce4ab..0000000000
--- a/cesar/bsu/aclf/test/utest/estimate_acl_freq_stable.sce
+++ /dev/null
@@ -1,54 +0,0 @@
-// SPiDCOM Technologies.
-// Nélio Laranjeiro
-// 16-05-2008
-// Cesar project.
-
-// Launch a test to verify the estimation function.
-
-// load the file, containing the function to generate a stable 50hz zero
-// cross.
-getf ('zc_capture.sce');
-getf ('estimateBP.sce');
-
-// C array writer
-getf('convertc.sce');
-
-// Initialise the environment.
-date_ntb = zeros (1,2);
-// 50 Hz in ticks.
-bp_ntb = 1e6;
-zc_ntb = bp_ntb / 4;
-
-// Number of points.
-nb_points = 1e3;
-
-cp = [date_ntb, bp_ntb, zc_ntb, bp_ntb];
-
-//Vector of points.
-result = zeros(nb_points,length(cp) + 1);
-
-for i = 1:nb_points
- cp = estimate_beacon_period (cp);
-
- result (i,:) = [cp, cp(1) - cp(2)];
- bp_ntb = cp(3) + 1e6;
-end
-
-// Write the result in a file.
-result_file = file('open', 'obj/result_stable.csv', 'unknown');
-fprintf (result_file, "Per, Per(ATU), Zc 1, Zc 2, diff\n");
-for i = 1:nb_points
- fprintf (result_file, "%d, %d, %d, %d, %d\n", result(i,5), int(result(i,5) / 256), result(i,1), result(i,2), result(6));
-end
-// Close the file.
-file('close', result_file);
-
-// Write the array.
-res = result(:,1);
-convertc_array ('obj/inc/table_stable.h', 'ac_stable', res);
-
-// Write the result of the simulation.
-res = result (:,5);
-convertc_array ('obj/inc/result_stable.h', 'result_ac_stable', res);
-
-exit;
diff --git a/cesar/bsu/aclf/test/utest/phy.py b/cesar/bsu/aclf/test/utest/phy.py
new file mode 100644
index 0000000000..353f909bd5
--- /dev/null
+++ b/cesar/bsu/aclf/test/utest/phy.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+
+#############################################################################
+# Copyright (C) 2011 Spidcom
+#
+# Phy class with necessary function to simulate the phy for ACLF.
+#############################################################################
+
+class Phy:
+ """Class phy containing some functions to simulate the Phy on Cesar."""
+
+ def __init__ (self, frequency):
+ """Initialise the phy class.
+ - frequency: the frequency to use with the test.
+ """
+ self.__frequency = frequency
+ self.__date_tck = 0
+ self.__zero_crossing_tck = 0
+
+ def zero_cross_interval (self):
+ """Compute the zero cross interval corresponding to the current
+ frequency."""
+ return int (25.0e6 / self.__frequency)
+
+ def zero_crossing (self):
+ """Get the phy last crossing date.
+ This function should return a phy crossing date in ticks.
+ """
+ return self.__zero_crossing_tck
+
+ def frequency_inc (self, val_hz):
+ """Increase frequency.
+ val: the value to increase in hertz."""
+ self.__frequency += val_hz
+
+ def frequency_dec (self, val_hz):
+ """Decrease frequency.
+ val: the value to decrease in hertz."""
+ self.__frequency -= val_hz
+ if self.__frequency < 0:
+ self.__frequency = 0
+
+ def frequency (self):
+ """Return the current frequency of the medium."""
+ return self.__frequency
+
+ def date (self):
+ """Get the current phy date."""
+ return self.__date_tck
+
+ def clock (self, tck):
+ """Make time goes on.
+ - tck: increase time of tck ticks."""
+ self.__date_tck += tck
+ zc_interval_tck = self.zero_cross_interval ()
+ zc_nb_interval_since_last_tck = \
+ (self.__date_tck - self.__zero_crossing_tck) \
+ / zc_interval_tck
+ zc_next_tck = self.__zero_crossing_tck \
+ + zc_nb_interval_since_last_tck * zc_interval_tck
+ self.__zero_crossing_tck = zc_next_tck
diff --git a/cesar/bsu/aclf/test/utest/src/bpsd.c b/cesar/bsu/aclf/test/utest/src/bpsd.c
index 476b8881e7..3913c3bdc5 100644
--- a/cesar/bsu/aclf/test/utest/src/bpsd.c
+++ b/cesar/bsu/aclf/test/utest/src/bpsd.c
@@ -13,12 +13,6 @@
#include "common/std.h"
#include "lib/test.h"
#include "common.h"
-#include "table_stable.h"
-#include "table_increase.h"
-#include "table_decrease.h"
-#include "result_stable.h"
-#include "result_increase.h"
-#include "result_decrease.h"
void
bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx);
@@ -29,261 +23,109 @@ 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;
-
-enum test_pwl_phy_t
-{
- TEST_ACLF_PHY_NONE,
- TEST_ACLF_PHY_AC_STABLE,
- TEST_ACLF_PHY_AC_INC,
- TEST_ACLF_PHY_AC_DEC,
- TEST_ACLF_PHY_ZC_TEST,
- TEST_ACLF_PHY_AC_CABLE
-};
-
-u32
-phy_clock_get_zero_cross_captured_date (phy_t *ctx)
-{
- bsu_aclf_test_phy_t *test = (bsu_aclf_test_phy_t *) ctx;
- switch (test->phy_type)
- {
- case TEST_ACLF_PHY_NONE:
- return test->zc;
- break;
- case TEST_ACLF_PHY_AC_STABLE:
- return ac_stable[test->table_index++];
- break;
- case TEST_ACLF_PHY_AC_INC:
- return ac_increase[test->table_index++];
- break;
- case TEST_ACLF_PHY_AC_DEC:
- return ac_decrease[test->table_index++];
- break;
- case TEST_ACLF_PHY_ZC_TEST:
- return zc_test[test->table_index++];
- break;
- default:
- return 0;
- break;
- }
-}
-
void
-test_case_aclf_estimate_beacon_period (test_t t)
+test_case_aclf_compute_bto (test_t t)
{
- u32 *tables[3] = {result_ac_stable, result_ac_increase,
- result_ac_decrease};
- enum bsu_aclf_test_aclf_phy_t test_phy_type[3] =
- {BSU_ACLF_TEST_ACLF_PHY_AC_STABLE, BSU_ACLF_TEST_ACLF_PHY_AC_INC,
- BSU_ACLF_TEST_ACLF_PHY_AC_DEC};
- bsu_aclf_test_t test;
- uint nb_iter;
- test_case_begin (t, "Beacon period estimation");
- test_begin (t, "AC Stable, increase, decrease")
- {
- uint i;
- for (i = 0; i < 3; i++)
- {
- bsu_aclf_test_init (&test);
- *((bsu_aclf_frequency_t*) &test.aclf->frequency) =
- BSU_ACLF_FREQ_50HZ;
- *((bsu_aclf_bp_t*) &test.aclf->bp) = BSU_ACLF_BP_50HZ_TCK;
- *((uint*) &test.aclf->zc) = BSU_ACLF_ZC_50HZ_TCK;
- test.aclf->beacon_period = test.aclf->bp;
- test.phy->phy_type = test_phy_type[i];
- for (nb_iter = 0; nb_iter < ac_stable_length; nb_iter ++)
- {
- bsu_aclf_ac_compute_beacon_period_start_date (test.aclf);
- test_fail_if (test.aclf->beacon_period
- != tables[i][nb_iter],
- "Estimation is false");
- }
- bsu_aclf_test_uninit (&test);
- }
- }
- test_end;
- test_begin (t, "AC stable, ZC = 740 000 tick")
+ test_case_begin (t, "BTO computation");
+ uint f, i;
+ float frequency;
+ bsu_aclf_test_t ctx;
+ test_begin (t, "Test beacon period date and BTO")
{
- bsu_aclf_test_init (&test);
- test.phy->phy_type = TEST_ACLF_PHY_NONE;
- *((uint*) &test.aclf->frequency) = BSU_ACLF_FREQ_50HZ;
- *((uint*) &test.aclf->bp) = BSU_ACLF_BP_50HZ_TCK;
- *((uint*) &test.aclf->zc) = BSU_ACLF_ZC_50HZ_TCK;
- test.aclf->beacon_period = test.aclf->bp;
- for (nb_iter = 0; nb_iter < zc_test_len; nb_iter ++)
+ for (f = 425; f < 691; f++)
{
- bsu_aclf_ac_compute_beacon_period_start_date (test.aclf);
- test_fail_unless (test.aclf->beacon_period
- == BSU_ACLF_BP_50HZ_TCK);
+ bsu_aclf_test_init (&ctx);
+ frequency = (float) f / 10;
+ ctx.phy->frequency_hz = frequency;
+ bsu_aclf_acl_frequency_detection (ctx.aclf);
+ bsu_aclf_ac_compute_beacon_period_start_date (ctx.aclf);
+ for (i = 1; i < BSU_ACLF_BPSD_NB; i++)
+ test_fail_unless (ctx.aclf->bpsd[i] != ctx.aclf->bpsd[i-1]);
+ for (i = 0; i < HPAV_BEACON_BTO_NB; i++)
+ test_fail_unless (
+ ctx.aclf->bto[i] != HPAV_BEACON_BTO_INVALID);
+ bsu_aclf_test_uninit (&ctx);
}
- bsu_aclf_test_uninit (&test);
}
test_end;
}
+/**
+ * Test BPSD computation from PowerLine and beacon reception.
+ * \param t the test context.
+ * \param frequency multiplied by 10 to avoid rounded values.
+ */
void
-test_case_aclf_compute_bto (test_t t)
+test_case_aclf_shift_bpsd_freq (test_t t, uint frequency)
{
- u32 *tables[3] = {result_ac_stable, result_ac_increase,
- result_ac_decrease};
- enum bsu_aclf_test_aclf_phy_t test_phy_type[3] =
- {BSU_ACLF_TEST_ACLF_PHY_AC_STABLE, BSU_ACLF_TEST_ACLF_PHY_AC_INC,
- BSU_ACLF_TEST_ACLF_PHY_AC_DEC};
- bsu_aclf_test_t test_cco, test_sta;
- uint nb_iter;
- test_case_begin (t, "BTO compute");
- test_begin (t, "AC Stable, increase and decrease")
+ test_within (t);
+ uint i;
+ u32 ntb_offset_tck = 1000;
+ bsu_aclf_test_t ctx;
+ bsu_aclf_test_init (&ctx);
+ ctx.phy->frequency_hz = (float) frequency / 10;
+ bsu_aclf_acl_frequency_detection (ctx.aclf);
+ uint beacon_period_cmp_tck = 50.0e6 / ((float) frequency / 10);
+ s16 bto[] = {0, 0, 0, 0};
+ /* Truncate the beacon period comparison. */
+ if (ctx.aclf->frequency == BSU_ACLF_FREQ_50HZ)
{
- uint i, j, bto_nb = 4, bpsd_nb = 6;
- s16 btos_cco[bto_nb], btos_sta[bto_nb];
- u32 bpsd_cco[bpsd_nb], bpsd_sta[bpsd_nb], bts;
- int bto;
- for (i = 0; i < 3; i++)
- {
- bsu_aclf_test_init (&test_cco);
- bsu_aclf_test_init (&test_sta);
- test_cco.phy->phy_type = test_phy_type[i];
- *((uint*) &test_cco.aclf->frequency) = BSU_ACLF_FREQ_50HZ;
- *((uint*) &test_cco.aclf->bp) = BSU_ACLF_BP_50HZ_TCK;
- *((uint*) &test_cco.aclf->zc) = BSU_ACLF_ZC_50HZ_TCK;
- *((uint*) &test_sta.aclf->frequency) = BSU_ACLF_FREQ_50HZ;
- *((uint*) &test_sta.aclf->bp) = BSU_ACLF_BP_50HZ_TCK;
- *((uint*) &test_sta.aclf->zc) = BSU_ACLF_ZC_50HZ_TCK;
- test_cco.aclf->beacon_period = test_cco.aclf->bp;
- test_sta.aclf->beacon_period = test_sta.aclf->bp;
- for (nb_iter = 0; nb_iter < ac_stable_length; nb_iter ++)
- {
- test_cco.phy->phy += tables[i][nb_iter];
- test_cco.phy->zc = test_cco.phy->phy - BSU_ACLF_ZC_50HZ_TCK;
- bsu_aclf_ac_compute_beacon_period_start_date (test_cco.aclf);
- bsu_aclf_bto (test_cco.aclf, btos_cco, bto_nb);
- bsu_aclf_beacon_period_start_date (test_cco.aclf, bpsd_cco,
- bpsd_nb);
- /* BTS value is use to simulate the STA beacon reception which
- * compute the beacon period start date using the BTS and the
- * BTOs of the central beacon. */
- bts = bpsd_cco[1];
- bsu_aclf_compute_beacon_period_start_date (test_sta.aclf, bts,
- btos_cco, 0, 0);
- bsu_aclf_bto (test_sta.aclf, btos_sta, bto_nb);
- bsu_aclf_beacon_period_start_date (test_sta.aclf, bpsd_sta,
- bpsd_nb);
- test_fail_unless (bpsd_sta[0] == bpsd_cco[1]);
- for (j = 0; j < HPAV_BEACON_BTO_NB; j++)
- {
- if (btos_sta[j] != HPAV_BEACON_BTO_INVALID)
- test_fail_unless (bpsd_sta[j+1] == bpsd_cco[j+2]);
- else
- test_fail_unless (bpsd_sta[j+1] == bts +
- (j+1)*test_sta.aclf->bp);
- }
-
- for (j = 0; j < HPAV_BEACON_BTO_NB; j++)
- {
- bto = bpsd_cco[j+2] - bpsd_cco[j+1] - test_cco.aclf->bp;
- if (ABS(bto) >> 15 == 0)
- {
- test_fail_unless (bpsd_cco[j+1] + test_cco.aclf->bp
- + btos_cco[j] == bpsd_cco[2+j]);
- }
- else
- test_fail_unless (btos_cco[j] ==
- HPAV_BEACON_BTO_INVALID);
- }
- }
- bsu_aclf_test_uninit (&test_cco);
- }
+ if (beacon_period_cmp_tck < BSU_ACLF_50HZ_CLK_MIN_TCK)
+ beacon_period_cmp_tck = BSU_ACLF_50HZ_CLK_MIN_TCK;
+ else if (beacon_period_cmp_tck > BSU_ACLF_50HZ_CLK_MAX_TCK)
+ beacon_period_cmp_tck = BSU_ACLF_50HZ_CLK_MAX_TCK;
}
- test_end;
-}
-
-void
-test_case_aclf_shift_bpsd (test_t t)
-{
- test_case_begin (t, "Shift bpsd");
- test_begin (t, "shift")
+ else
+ {
+ if (beacon_period_cmp_tck < BSU_ACLF_60HZ_CLK_MIN_TCK)
+ beacon_period_cmp_tck = BSU_ACLF_60HZ_CLK_MIN_TCK;
+ else if (beacon_period_cmp_tck > BSU_ACLF_60HZ_CLK_MAX_TCK)
+ beacon_period_cmp_tck = BSU_ACLF_60HZ_CLK_MAX_TCK;
+ }
+ bsu_aclf_ac_compute_beacon_period_start_date (ctx.aclf);
+ u32 bpsd_date = ctx.aclf->bpsd[1];
+ while (!lesseq_mod2p32 (ctx.aclf->bpsd[1], phy_date ()))
+ ;
+ bsu_aclf_shift_beacon_period_start_date (ctx.aclf);
+ test_fail_unless (less_mod2p32 (bpsd_date, ctx.aclf->bpsd[1]));
+ for (i = 1; i < BSU_ACLF_BPSD_NB; i++)
{
- uint i;
- u32 now = phy_date ();
- bsu_aclf_test_t test;
- bsu_aclf_test_init (&test);
- for (i = 0; i < COUNT (test.aclf->bpsd); i++)
- test.aclf->bpsd[i] = i * BSU_ACLF_BP_50HZ_TCK + now;
- test.aclf->beacon_period = BSU_ACLF_BP_50HZ_TCK;
- test.phy->phy = test.aclf->bpsd[1];
- bsu_aclf_shift_beacon_period_start_date (test.aclf);
test_fail_unless (
- test.aclf->bpsd[1]
- == bsu_aclf_beacon_period_start_date_next (test.aclf));
- for (i = 0; i < BSU_ACLF_BPSD_NB - 1; i++)
- test_fail_unless (test.aclf->bpsd[i] == now + (i+1) *
- BSU_ACLF_BP_50HZ_TCK);
- bsu_aclf_test_uninit (&test);
+ less_mod2p32 (ctx.aclf->bpsd[i-1], ctx.aclf->bpsd[i]));
+ int diff_tck =
+ beacon_period_cmp_tck - (ctx.aclf->bpsd[i] - ctx.aclf->bpsd[i-1]);
+ test_fail_unless (diff_tck <= 1 && diff_tck >= -1);
}
- test_end;
-}
-
-void
-test_case_aclf_shift_compute_shift_bpsd (test_t t)
-{
- test_case_begin (t, "Shift compute and shift bpsd");
- test_begin (t, "no name")
+ /* Compare BTOs. */
+ for (i = 0; i < HPAV_BEACON_BTO_NB; i++)
{
- uint i, j;
- u32 now = phy_date ();
- bsu_aclf_test_t test;
- bsu_aclf_test_init (&test);
- bsu_aclf_acl_frequency_detection (test.aclf);
- for (j = 0; j < 3; j++)
- {
- for (i = 0; i < COUNT (test.aclf->bpsd); i++)
- test.aclf->bpsd[i] = i * BSU_ACLF_BP_50HZ_TCK + now;
- test.aclf->beacon_period = BSU_ACLF_BP_50HZ_TCK;
- test.phy->phy = test.aclf->bpsd[1];
- if (j != 1)
- bsu_aclf_shift_beacon_period_start_date (test.aclf);
- else
- {
- u32 ntb_tick_offset = 1043;
- u32 bts = test.aclf->bpsd[0] + ntb_tick_offset + test.aclf->bp;
- s16 bto[4] = {0, 0, 0, 0};
- uint k;
- for (k = 0; k < BSU_ACLF_BPSD_NB; k++)
- test.aclf->bpsd[k] = 0;
- bsu_aclf_compute_beacon_period_start_date (test.aclf,
- bts, bto, 0,
- ntb_tick_offset);
- }
- test_fail_unless (
- test.aclf->bpsd[1]
- == bsu_aclf_beacon_period_start_date_next (test.aclf));
- for (i = 0; i < BSU_ACLF_BPSD_NB; i++)
- test_fail_unless (test.aclf->bpsd[i] == now + (i+1) *
- BSU_ACLF_BP_50HZ_TCK);
- }
- bsu_aclf_test_uninit (&test);
+ bto[i] = beacon_period_cmp_tck -
+ ctx.aclf->beacon_period_theo_tck;
+ int bto_diff = ctx.aclf->bto[i] - bto[i];
+ test_fail_unless (bto_diff >= -1 && bto_diff <= 1);
}
- test_end;
+ /* Compute the next beacon period using a received information
+ * from the beacon. */
+ u32 bts = ctx.aclf->bpsd[1] + ntb_offset_tck;
+ bsu_aclf_compute_beacon_period_start_date (
+ ctx.aclf, bts, bto, 0, ntb_offset_tck);
+ for (i = 1; i < BSU_ACLF_BPSD_NB - 1; i++)
+ {
+ u32 diff_tck = ctx.aclf->bpsd[i] - ctx.aclf->bpsd[i-1];
+ test_fail_unless (diff_tck == beacon_period_cmp_tck);
+ }
+ bsu_aclf_test_uninit (&ctx);
}
void
-test_case_aclf_beacon_period (test_t t)
+test_case_aclf_shift_bpsd (test_t t)
{
- test_case_begin (t, "Beacon period read from aclf in TCK and ATU");
- test_begin (t, "test")
+ uint f;
+ test_case_begin (t, "Shift bpsd");
+ test_begin (t, "shift")
{
- uint i;
- bsu_aclf_test_t test;
- bsu_aclf_test_init (&test);
- bsu_aclf_acl_frequency_detection (test.aclf);
- for (i = 0; i < COUNT (test.aclf->bpsd); i++)
- test.aclf->bpsd[i] = i * BSU_ACLF_BP_50HZ_TCK;
- test_fail_unless (bsu_aclf_beacon_period_atu (test.aclf) == 3907);
- for (i = 0; i < COUNT (test.aclf->bpsd); i++)
- test.aclf->bpsd[i] = i * 999936;
- test_fail_unless (bsu_aclf_beacon_period_atu (test.aclf) == 3906);
- bsu_aclf_test_uninit (&test);
+ for (f = 425; f < 691; f++)
+ test_case_aclf_shift_bpsd_freq (t, f);
}
test_end;
}
@@ -292,9 +134,6 @@ void
test_suite_aclf__bpsd_accurate (test_t t)
{
test_suite_begin (t, "Beacon Period Start Date accurate");
- test_case_aclf_estimate_beacon_period (t);
test_case_aclf_compute_bto (t);
test_case_aclf_shift_bpsd (t);
- test_case_aclf_shift_compute_shift_bpsd (t);
- test_case_aclf_beacon_period (t);
}
diff --git a/cesar/bsu/aclf/test/utest/src/common.c b/cesar/bsu/aclf/test/utest/src/common.c
index a71115aaf4..ca654d0cd5 100644
--- a/cesar/bsu/aclf/test/utest/src/common.c
+++ b/cesar/bsu/aclf/test/utest/src/common.c
@@ -12,7 +12,6 @@
*/
#include "common/std.h"
#include "hal/timer/timer.h"
-#include "zc_cross.h"
#include "common.h"
#include <string.h>
@@ -24,6 +23,7 @@ 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));
+ phy_test_global.use_phy_clock = true;
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;
@@ -37,23 +37,35 @@ bsu_aclf_test_uninit (bsu_aclf_test_t *t)
bsu_aclf_uninit (t->aclf);
}
-static void
-phy_zero_cross (bsu_aclf_test_phy_t *test)
+static u32
+phy_zero_cross_interval (bsu_aclf_test_phy_t *ctx)
{
- u32 last_zc;
- /* Compute last ZC. */
- if (test->frequency)
- {
- last_zc = test->zc + zero_cross[test->zc_cross_index];
- if (lesseq_mod2p32 (last_zc, test->phy))
- test->zc = last_zc;
- }
+ return 25.0e6 / ctx->frequency_hz;
+}
+
+void
+phy_clock (bsu_aclf_test_phy_t *ctx, u32 ticks)
+{
+ ctx->phy_date += ticks;
+ uint zc_interval_tck = phy_zero_cross_interval (ctx);
+ uint zc_nb_interval_since_last_date =
+ (ctx->phy_date - ctx->zero_crossing_date)
+ / zc_interval_tck;
+ u32 zc_next_date = ctx->zero_crossing_date
+ + zc_nb_interval_since_last_date * zc_interval_tck;
+ ctx->zero_crossing_date = zc_next_date;
}
u32
phy_date (void)
{
- phy_zero_cross (&phy_test_global);
- phy_test_global.phy += 100;
- return phy_test_global.phy;
+ if (phy_test_global.use_phy_clock)
+ phy_clock (&phy_test_global, 1000);
+ return phy_test_global.phy_date;
+}
+
+u32
+phy_clock_get_zero_cross_captured_date (phy_t *ctx)
+{
+ return phy_test_global.zero_crossing_date;
}
diff --git a/cesar/bsu/aclf/test/utest/src/freq.c b/cesar/bsu/aclf/test/utest/src/freq.c
index 37ae02654f..a821eab289 100644
--- a/cesar/bsu/aclf/test/utest/src/freq.c
+++ b/cesar/bsu/aclf/test/utest/src/freq.c
@@ -14,41 +14,149 @@
#include "mac/common/timings.h"
#include "lib/test.h"
#include "lib/rnd.h"
+#include "bsu/aclf/aclf.h"
#include "bsu/aclf/test/utest/common.h"
+#include "hal/arch/arch.h"
+
+void
+bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx);
void
bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx);
+/** Verify the beacon period estimated is correct.
+ * \param t the unit test context.
+ * \param ctx the bsu_aclf_test context.
+ * \param frequency the frequency value used for the test.
+ */
+void
+test_aclf_verify_beacon_period (
+ test_t t, bsu_aclf_test_t *ctx, float frequency)
+{
+ test_within (t);
+ /* Compute the beacon period from the frequency used by the test.
+ * 25.0e6/frequency == PowerLine cycle in ticks.
+ * Beacon period is twice the PowerLine cycle.*/
+ int diff_tck = 50.0e6 / frequency - ctx->aclf->beacon_period_tck;
+ uint clk_min_tck =
+ ctx->aclf->beacon_period_theo_tck
+ - BITS_ONES (HPAV_BEACON_BTO_VALID_BITS);
+ uint clk_max_tck =
+ ctx->aclf->beacon_period_theo_tck
+ + BITS_ONES (HPAV_BEACON_BTO_VALID_BITS);
+ test_fail_unless (
+ ctx->aclf->beacon_period_tck == clk_min_tck
+ || ctx->aclf->beacon_period_tck == clk_max_tck
+ || (diff_tck >= -25 && diff_tck <= 25),
+ "Frequency %0.1f bp_tck %d diff_tck %d",
+ frequency, ctx->aclf->beacon_period_tck, diff_tck);
+}
+
+/**
+ * Make the frequency increase or decrease during the test.
+ * \param t test context.
+ * \param freq Initial frequency (float value) [42.5, 69].
+ * \param step Increase or decrease step (float value).
+ */
+void
+test_aclf_frequency_variation (test_t t, volatile int frequency, int step)
+{
+ uint i;
+ bsu_aclf_test_t ctx;
+ test_begin (t, "frequency variation")
+ {
+ bsu_aclf_test_init (&ctx);
+ ctx.phy->frequency_hz = (float) frequency / 10;
+ ctx.phy->use_phy_clock = true;
+ bsu_aclf_acl_frequency_detection (ctx.aclf);
+ /* Do not set it before the frequency detection to avoid an
+ * infinite loop. */
+ ctx.phy->use_phy_clock = false;
+ for (;
+ (ctx.aclf->frequency == BSU_ACLF_FREQ_50HZ
+ && frequency <= 575 && frequency >= 425)
+ || (ctx.aclf->frequency == BSU_ACLF_FREQ_60HZ
+ && frequency <= 690 && frequency >= 510)
+ ; frequency += step)
+ {
+ ctx.phy->frequency_hz = (float) frequency / 10;
+ for (i = 0; i < 100; i++)
+ {
+ phy_clock (ctx.phy, ctx.aclf->beacon_period_tck);
+ bsu_aclf_ac_compute_beacon_period_start_date (ctx.aclf);
+ }
+ test_aclf_verify_beacon_period (t, &ctx, ctx.phy->frequency_hz);
+ }
+ bsu_aclf_test_uninit (&ctx);
+ }
+ test_end;
+}
+
+void
+test_aclf_frequency_inc_dec (test_t t, volatile int freq)
+{
+ test_begin (t, "Increasing/Decreasing")
+ {
+ uint i, step = 1;
+ bsu_aclf_test_t ctx;
+ bsu_aclf_test_init (&ctx);
+ ctx.phy->frequency_hz = (float) freq / 10;
+ ctx.phy->use_phy_clock = true;
+ bsu_aclf_acl_frequency_detection (ctx.aclf);
+ /* Do not set it before the frequency detection to avoid an
+ * infinite loop. */
+ ctx.phy->use_phy_clock = false;
+ for (;
+ (ctx.aclf->frequency == BSU_ACLF_FREQ_50HZ
+ && freq <= 575 && freq >= 425)
+ || (ctx.aclf->frequency == BSU_ACLF_FREQ_60HZ
+ && freq >= 510 && freq <= 690);
+ freq += step)
+ {
+ ctx.phy->frequency_hz = (float) freq / 10;
+ for (i = 0; i < 100; i++)
+ {
+ phy_clock (ctx.phy, ctx.aclf->beacon_period_tck);
+ bsu_aclf_ac_compute_beacon_period_start_date (ctx.aclf);
+ }
+ test_aclf_verify_beacon_period (t, &ctx, (float) freq / 10);
+ /* Reverse step if frequency is 69 Hz. */
+ if ((ctx.aclf->frequency == BSU_ACLF_FREQ_50HZ && freq == 575)
+ || (ctx.aclf->frequency == BSU_ACLF_FREQ_60HZ && freq == 690))
+ step = -step;
+ }
+ bsu_aclf_test_uninit (&ctx);
+ }
+ test_end;
+}
+
void
test_case_aclf_all_frequencies (test_t t)
{
test_case_begin (t, "All frequency possible");
- test_begin (t, "Frequency increase.")
+ test_begin (t, "Frequency.")
{
- u32 acl_zc;
- lib_rnd_t rnd;
- lib_rnd_init (&rnd, 0x12324);
- bsu_aclf_test_t test;
- bsu_aclf_test_init (&test);
- for (test.phy->frequency = 40, test.phy->zc_cross_index = 0;
- test.phy->frequency <= 80;
- test.phy->frequency++, test.phy->zc_cross_index++)
+ uint f;
+ float frequency;
+ bsu_aclf_test_t ctx;
+ bsu_aclf_test_init (&ctx);
+ for (f = 425; f < 691; f++)
{
- if (test.phy->frequency)
- acl_zc = MAC_MS_TO_TCK (1000 / test.phy->frequency) / 2;
- else
- acl_zc = 0;
- test.phy->phy = lib_rnd32 (&rnd);
- test.phy->zc = test.phy->phy - acl_zc + 1000;
- bsu_aclf_acl_frequency_detection (test.aclf);
- if (test.phy->frequency < 56)
- test_fail_unless (test.aclf->frequency == BSU_ACLF_FREQ_50HZ);
- else
- test_fail_unless (test.aclf->frequency == BSU_ACLF_FREQ_60HZ);
+ frequency = (float) f / 10;
+ ctx.phy->frequency_hz = frequency;
+ bsu_aclf_acl_frequency_detection (ctx.aclf);
+ test_aclf_verify_beacon_period (t, &ctx, frequency);
}
- bsu_aclf_test_uninit (&test);
+ bsu_aclf_test_uninit (&ctx);
}
test_end;
+ test_case_begin (t, "Increase, decrease");
+ test_aclf_frequency_variation (t, 425, 1);
+ test_aclf_frequency_variation (t, 551, 1);
+ test_aclf_frequency_variation (t, 690, -1);
+ test_aclf_frequency_variation (t, 550, -1);
+ test_aclf_frequency_inc_dec (t, 425);
+ test_aclf_frequency_inc_dec (t, 551);
}
void
diff --git a/cesar/bsu/aclf/test/utest/src/misc.c b/cesar/bsu/aclf/test/utest/src/misc.c
index 811c112d3e..1579f7dfec 100644
--- a/cesar/bsu/aclf/test/utest/src/misc.c
+++ b/cesar/bsu/aclf/test/utest/src/misc.c
@@ -23,27 +23,8 @@ void
bsu_aclf_timer_event (void *user_data);
void
-test_case_aclf__beacon_period (test_t test)
-{
- test_case_begin (test, "ACLF beacon period");
- test_begin (test, "Get the beacon period")
- {
- u32 bpsd [4] = { 0, 30, 70, 150 };
- uint i;
- bsu_aclf_test_t t;
- bsu_aclf_test_init (&t);
- for (i = 0; i < COUNT(bpsd); i++)
- t.aclf->bpsd[i] = bpsd[i];
- for (i = 0; i < COUNT(bpsd) - 1; i++)
- {
- test_fail_unless (bpsd[i+1] - bpsd[i]
- == bsu_aclf_beacon_period_tck (t.aclf));
- bsu_aclf_shift_beacon_period_start_date (t.aclf);
- }
- bsu_aclf_test_uninit (&t);
- }
- test_end;
-}
+bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx);
+
void
test_case_aclf__timer (test_t test)
@@ -52,6 +33,8 @@ test_case_aclf__timer (test_t test)
uint i;
u32 bpsd[4];
bsu_aclf_test_init (&ctx);
+ ctx.phy->frequency_hz = 50.0;
+ bsu_aclf_acl_frequency_detection (ctx.aclf);
test_case_begin (test, "Timer event");
test_begin (test, "ACL tracker")
{
@@ -62,28 +45,28 @@ test_case_aclf__timer (test_t test)
test_fail_unless (bpsd[i+1] - bpsd[i]
== bsu_aclf_beacon_period_tck (ctx.aclf));
u32 old = bpsd[0];
- ctx.phy->phy = bpsd[1];
+ ctx.phy->phy_date = 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_tck (ctx.aclf));
- test_fail_unless (old + ctx.aclf->bp == bpsd[0]);
+ test_fail_unless (old + ctx.aclf->beacon_period_theo_tck == bpsd[0]);
}
test_end;
test_begin (test, "Station behavior")
{
bsu_aclf_aclsc (ctx.aclf, false);
u32 old = bpsd[0];
- ctx.phy->phy = bpsd[1];
+ ctx.phy->phy_date = 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_tck (ctx.aclf));
- test_fail_unless (old + ctx.aclf->bp == bpsd[0]);
+ test_fail_unless (old + ctx.aclf->beacon_period_theo_tck == bpsd[0]);
}
test_end;
bsu_aclf_test_uninit (&ctx);
@@ -93,6 +76,5 @@ 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);
}
diff --git a/cesar/bsu/aclf/test/utest/zc_capture.sce b/cesar/bsu/aclf/test/utest/zc_capture.sce
deleted file mode 100644
index e74574d021..0000000000
--- a/cesar/bsu/aclf/test/utest/zc_capture.sce
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPiDCOM Technologies.
-// Nélio Laranjeiro
-// 16-05-2008
-// Cesar project.
-
-// This script will provide a function to generate a perfect 50 Hz frequency
-// AC Line based on the NTB date.
-
-
-// Function to simulate the frequency of the AC line.
-// @param phy the previous value provided.
-// @Return phy + 250 000
-function phy = phy_clock_get_zero_cross (phy)
-
-phy = phy + 1000000;
-return phy;
-
-endfunction
diff --git a/cesar/bsu/aclf/test/utest/zc_capture_decrease.sce b/cesar/bsu/aclf/test/utest/zc_capture_decrease.sce
deleted file mode 100644
index e094f2e1c7..0000000000
--- a/cesar/bsu/aclf/test/utest/zc_capture_decrease.sce
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPiDCOM Technologies.
-// Nélio Laranjeiro
-// 16-05-2008
-// Cesar project.
-
-// This script will provide a function to generate a 50 Hz frequency
-// AC Line based on the NTB date with a little jitter.
-
-
-// Function to simulate the frequency of the AC line.
-// @param phy the previous value provided.
-// @param var The variation of frequency.
-// @Return phy + 250 000
-function phy = phy_clock_get_zero_cross (phy)
-
-var = int(rand (1) * 100000);
-phy = phy + 1000000 - var;
-return phy;
-
-endfunction
diff --git a/cesar/bsu/aclf/test/utest/zc_capture_increase.sce b/cesar/bsu/aclf/test/utest/zc_capture_increase.sce
deleted file mode 100644
index c412c6f689..0000000000
--- a/cesar/bsu/aclf/test/utest/zc_capture_increase.sce
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPiDCOM Technologies.
-// Nélio Laranjeiro
-// 16-05-2008
-// Cesar project.
-
-// This script will provide a function to generate a 50 Hz frequency
-// AC Line based on the NTB date with a little jitter.
-
-
-// Function to simulate the frequency of the AC line.
-// @param phy the previous value provided.
-// @param var The variation of frequency.
-// @Return phy + 250 000
-function phy = phy_clock_get_zero_cross (phy)
-
-var = int(rand (1) * 1000);
-phy = phy + 1e6 + var;
-return phy;
-
-endfunction
diff --git a/cesar/bsu/test/utest/src/bsut.c b/cesar/bsu/test/utest/src/bsut.c
index 948c1d699d..e6b1fddbfe 100644
--- a/cesar/bsu/test/utest/src/bsut.c
+++ b/cesar/bsu/test/utest/src/bsut.c
@@ -613,6 +613,7 @@ test_case_bsu_persistent_schedules_update__cscma_cscd_permanent (
bsu_beacon_t beacon;
test_within (test);
bsu_test_init (&t);
+ bsu_aclf_activate (t.bsu->aclf, true);
memset (&t.bsu->sta_avln->beacon, 0, sizeof (bsu_beacon_t));
t.bsu->sta_avln->beacon.vf.nm = BSU_BEACON_NM_CSMA_ONLY;
bsu_test_create_beacon (&t, &beacon);
@@ -641,6 +642,7 @@ test_case_bsu_persistent_schedules_update__cscma_cscd_non_permanent (
bsu_beacon_t beacon;
test_within (test);
bsu_test_init (&t);
+ bsu_aclf_activate (t.bsu->aclf, true);
memset (&t.bsu->sta_avln->beacon, 0, sizeof (bsu_beacon_t));
t.bsu->sta_avln->beacon.vf.nm = BSU_BEACON_NM_CSMA_ONLY;
bsu_test_create_beacon (&t, &beacon);
diff --git a/cesar/bsu/test/utest/src/schedules.c b/cesar/bsu/test/utest/src/schedules.c
index fddab97223..7c516937d9 100644
--- a/cesar/bsu/test/utest/src/schedules.c
+++ b/cesar/bsu/test/utest/src/schedules.c
@@ -261,8 +261,9 @@ test_case_ca_schedules_intellon (test_t test)
uint i;
for (i = 0; i < COUNT (t.bsu->aclf->bpsd); i++)
t.bsu->aclf->bpsd[i] = i * BSU_ACLF_BP_50HZ_TCK;
- t.bsu->aclf->beacon_period = BSU_ACLF_BP_50HZ_TCK;
- *((uint*) &t.bsu->aclf->bp) = BSU_ACLF_BP_50HZ_TCK;
+ t.bsu->aclf->beacon_period_tck = BSU_ACLF_BP_50HZ_TCK;
+ *((uint*) &t.bsu->aclf->beacon_period_theo_tck) =
+ BSU_ACLF_BP_50HZ_TCK;
pbproc_tx_beacon_params_t btx;
pbproc_rx_beacon_params_t brx;
memset (&brx, 0, sizeof (pbproc_rx_beacon_params_t));
diff --git a/cesar/bsu/test/utest/src/tests.c b/cesar/bsu/test/utest/src/tests.c
index 85e47ec05d..48b6c5a519 100644
--- a/cesar/bsu/test/utest/src/tests.c
+++ b/cesar/bsu/test/utest/src/tests.c
@@ -18,6 +18,8 @@
#include <string.h>
#include "bsu/inc/context.h"
+static struct bsu_aclf_test_phy_t phy_test_global;
+
static int
bsu_trace_buffer_dbg_dump_callback (void *user, const char *text,
uint text_size)
@@ -53,6 +55,10 @@ bsu_test_init (bsu_test_t *ctx)
{
dbg_assert (ctx);
trace_init ();
+ phy_test_global.frequency_hz = 50.0;
+ phy_test_global.phy_date = 0;
+ phy_test_global.zero_crossing_date = 0;
+ phy_test_global.use_phy_clock = true;
ctx->mac_config.tei = 0x0;
ctx->mac_config.sta_mac_address = 0x123456789abcull;
ctx->mac_store = mac_store_init ();
@@ -78,6 +84,7 @@ bsu_test_uninit (bsu_test_t *ctx)
dbg_assert (ctx);
trace_bundle_dump_all ("dbg", bsu_trace_buffer_dbg_dump_callback, NULL);
bsu_uninit (ctx->bsu);
+ bsu_aclf_uninit (ctx->bsu->aclf);
mac_store_uninit (ctx->mac_store);
trace_uninit ();
}
@@ -496,3 +503,36 @@ bsu_test_avln_create (bsu_test_t *ctx, bsu_avln_t *avln)
bsu_test_schedules_persistent (ctx, &avln->beacon.bmis.ps);
bsu_test_schedules_non_persistent (ctx, &avln->beacon.bmis.nps);
}
+
+static u32
+phy_zero_cross_interval (bsu_aclf_test_phy_t *ctx)
+{
+ return 25.0e6 / ctx->frequency_hz;
+}
+
+void
+phy_clock (bsu_aclf_test_phy_t *ctx, u32 ticks)
+{
+ ctx->phy_date += ticks;
+ uint zc_interval_tck = phy_zero_cross_interval (ctx);
+ uint zc_nb_interval_since_last_date =
+ (ctx->phy_date - ctx->zero_crossing_date)
+ / zc_interval_tck;
+ u32 zc_next_date = ctx->zero_crossing_date
+ + zc_nb_interval_since_last_date * zc_interval_tck;
+ ctx->zero_crossing_date = zc_next_date;
+}
+
+u32
+phy_date (void)
+{
+ if (phy_test_global.use_phy_clock)
+ phy_clock (&phy_test_global, 1000);
+ return phy_test_global.phy_date;
+}
+
+u32
+phy_clock_get_zero_cross_captured_date (phy_t *ctx)
+{
+ return phy_test_global.zero_crossing_date;
+}
diff --git a/cesar/bsu/test/utest/tests.h b/cesar/bsu/test/utest/tests.h
index ff59576c09..aa5ac5b1a8 100644
--- a/cesar/bsu/test/utest/tests.h
+++ b/cesar/bsu/test/utest/tests.h
@@ -21,6 +21,20 @@
#include "mac/sar/sar.h"
#include "bsu/beacon/beacon.h"
+struct bsu_aclf_test_phy_t
+{
+ /** Frequency simulation. */
+ float frequency_hz;
+ /** Phy date. */
+ u32 phy_date;
+ /** Zero crossing. */
+ u32 zero_crossing_date;
+ /** False to use phy clock function to make time goes on,
+ * or false to increase time by 1000 ticks on phy_date function call. */
+ bool use_phy_clock;
+};
+typedef struct bsu_aclf_test_phy_t bsu_aclf_test_phy_t;
+
struct bsu_test_ca_t
{
/* Beacon periods computed for the CA. */
diff --git a/cesar/common/defs/homeplugAV.h b/cesar/common/defs/homeplugAV.h
index fb3650c0a8..39da6f293e 100644
--- a/cesar/common/defs/homeplugAV.h
+++ b/cesar/common/defs/homeplugAV.h
@@ -84,6 +84,8 @@ typedef enum hpav_access_t hpav_access_t;
/** Invalid value for the BTO.*/
#define HPAV_BEACON_BTO_INVALID ((s16)0x8000)
+/** Number of valid bits in BTO. */
+#define HPAV_BEACON_BTO_VALID_BITS 15
/** Value of the permanent persistent schedule CSCD
* Only valid if operating in CSMA only mode.. */
diff --git a/cesar/common/tests/tests b/cesar/common/tests/tests
index b8b2a25445..c2c8e787ab 100644
--- a/cesar/common/tests/tests
+++ b/cesar/common/tests/tests
@@ -502,3 +502,4 @@ bsu/ntb: ./obj/ntb
bsu/aclf/test/utest:
make
bsu/aclf: ./obj/aclf
+beacon_estimation: python beacon_period.py
diff --git a/cesar/cp/av/cco/bw/src/bw.c b/cesar/cp/av/cco/bw/src/bw.c
index 865b990d81..ffc99cd14f 100644
--- a/cesar/cp/av/cco/bw/src/bw.c
+++ b/cesar/cp/av/cco/bw/src/bw.c
@@ -31,7 +31,8 @@ cp_av_cco_bw_schedules_default (cp_t *ctx)
alloc = cp_cco_bw_alloc_init (ctx);
alloc->stpf = false;
alloc->end_time_atu =
- MAC_TCK_TO_ATU(BSU_ACLF_BP_50HZ_TCK + CP_AV_CCO_BW_ALLOC_MIN_SIZE_TCK);
+ MAC_TCK_TO_ATU(BSU_ACLF_50HZ_CLK_MAX_TCK
+ + CP_AV_CCO_BW_ALLOC_MIN_SIZE_TCK);
alloc->glid = MAC_LID_SHARED_CSMA;
alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_PERSISTENT;
alloc->pscd = 0;