summaryrefslogtreecommitdiff
path: root/cesar/hal
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/hal')
-rw-r--r--cesar/hal/phy/Module2
-rw-r--r--cesar/hal/phy/defs.h17
-rw-r--r--cesar/hal/phy/inc/tonemask.h41
-rw-r--r--cesar/hal/phy/src/phy.c29
-rw-r--r--cesar/hal/phy/src/tonemask.c91
-rw-r--r--cesar/hal/phy/test/tonemask/Makefile11
-rw-r--r--cesar/hal/phy/test/tonemask/override/hal/phy/defs.h35
-rw-r--r--cesar/hal/phy/test/tonemask/src/test_tonemask.c144
8 files changed, 338 insertions, 32 deletions
diff --git a/cesar/hal/phy/Module b/cesar/hal/phy/Module
index df621b8db7..97e49643da 100644
--- a/cesar/hal/phy/Module
+++ b/cesar/hal/phy/Module
@@ -1,5 +1,5 @@
SOURCES := access.c pbdma.c phy.c pratic.c rx.c tx.c resys.c vsr.S \
- bridgedma.c hlut.c
+ bridgedma.c hlut.c tonemask.c
MODULES := hal/phy/spoc
ifeq ($(CONFIG_TRACE),y)
diff --git a/cesar/hal/phy/defs.h b/cesar/hal/phy/defs.h
index 1c2a3d5075..362fe3bbb5 100644
--- a/cesar/hal/phy/defs.h
+++ b/cesar/hal/phy/defs.h
@@ -35,11 +35,17 @@
/** Total number of OFDM carrier, also counting unusable ones. */
#define PHY_ALL_CARRIER_NB 1536
-/** Number of OFDM carrier for HP10, defined by the hardware. */
-#define PHY_HP10_CARRIER_NB 144
+/** Number of AV carriers per HP10 carrier. */
+#define PHY_HP10_CARRIER_FACTOR 8
-/** Number of first OFDM carrier for HP10, defined by the hardware. */
-#define PHY_HP10_CARRIER_OFFSET 10
+/** Number of OFDM carrier for HP10. */
+#define PHY_HP10_CARRIER_NB \
+ ((PHY_CARRIER_OFFSET + PHY_CARRIER_NB - 1) / PHY_HP10_CARRIER_FACTOR \
+ - PHY_HP10_CARRIER_OFFSET + 1)
+
+/** Number of first OFDM carrier for HP10. */
+#define PHY_HP10_CARRIER_OFFSET \
+ CEIL_DIV (PHY_CARRIER_OFFSET, PHY_HP10_CARRIER_FACTOR)
/** Number of words needed to define a tonemask. */
#define PHY_TONEMASK_WORDS ((PHY_CARRIER_NB + 32 - 1) / 32)
@@ -53,6 +59,9 @@
/** Number of bytes needed to define a tonemap. */
#define PHY_TONEMAP_SIZE (PHY_TONEMAP_WORDS * 4)
+/** Number of words in HP10 extended tonemask. */
+#define PHY_HP10_TONEMASK_WORDS 6
+
/** Delay to find a preamble, defined by the hardware, not precise.
* At this time, we got confirmation from HW.
* False alarm is not possible anymore. */
diff --git a/cesar/hal/phy/inc/tonemask.h b/cesar/hal/phy/inc/tonemask.h
new file mode 100644
index 0000000000..f2af794019
--- /dev/null
+++ b/cesar/hal/phy/inc/tonemask.h
@@ -0,0 +1,41 @@
+#ifndef hal_phy_inc_tonemask_h
+#define hal_phy_inc_tonemask_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2013 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/phy/inc/tonemask.h
+ * \brief HAL Phy tonemask tools.
+ * \ingroup hal_phy
+ */
+
+/** Number of neighbors to look at to make a HP10 tonemask. */
+#define PHY_HP10_TONEMASK_NEIGHBORS 1
+
+BEGIN_DECLS
+
+/**
+ * Compute amplitude map which corresponds to tonemask.
+ * \param tonemask tonemask data
+ * \param ampmap room to store amplitude map (same size as tonemap,
+ * PHY_TONEMAP_WORDS)
+ */
+void
+phy_tonemask_to_ampmap (const u32 *tonemask, u32 *ampmap);
+
+/**
+ * Compute HP10 tonemask which corresponds to tonemask.
+ * \param tonemask tonemask data
+ * \param tonemask10 room to store HP10 tonemask (PHY_HP10_TONEMASK_WORDS),
+ * can directly map to hardware registers
+ */
+void
+phy_tonemask_to_tonemask10 (const u32 *tonemask, volatile u32 *tonemask10);
+
+END_DECLS
+
+#endif /* hal_phy_inc_tonemask_h */
diff --git a/cesar/hal/phy/src/phy.c b/cesar/hal/phy/src/phy.c
index 3f34f7192d..c2cc692ccf 100644
--- a/cesar/hal/phy/src/phy.c
+++ b/cesar/hal/phy/src/phy.c
@@ -19,6 +19,7 @@
#include "inc/resys.h"
#include "inc/hlut.h"
#include "inc/dini_pamela.h"
+#include "inc/tonemask.h"
#include "hal/phy/spoc/spoc.h"
@@ -876,27 +877,6 @@ phy_set_tunable_param (phy_t *ctx, const u32 *tonemask, uint carrier_nb)
phy_hlut_set_tunable ();
}
-static void
-phy_tonemask_to_ampmap (u32 *tonemask, u32 *ampmap)
-{
- uint i, j;
- u32 tmw = 0, amw;
- for (i = 0; i < PHY_TONEMAP_WORDS; i++)
- {
- if (i % 4 == 0)
- tmw = *tonemask++;
- amw = 0;
- for (j = 0; j < 8; j++)
- {
- amw >>= 4;
- if (tmw & 1)
- amw |= 0xf0000000;
- tmw >>= 1;
- }
- *ampmap++ = amw;
- }
-}
-
void
phy_set_tonemask (phy_t *ctx, u32 *tonemask, uint carrier_nb)
{
@@ -950,12 +930,7 @@ phy_set_tonemask (phy_t *ctx, u32 *tonemask, uint carrier_nb)
(NB_CARRIER, carrier_nb),
(NB_CARRIER_10, PHY_CARRIER_NB_10_FC));
/* Set HP 1.0 parameters. */
- PHY_DSPSS_HP10_MASK_0 = 0x0C060F01;
- PHY_DSPSS_HP10_MASK_1 = 0xC0000400;
- PHY_DSPSS_HP10_MASK_2 = 0x000C0001;
- PHY_DSPSS_HP10_MASK_3 = 0x0060001E;
- PHY_DSPSS_HP10_MASK_4 = 0x0000FFE0;
- PHY_DSPSS_HP10_MASK_5 = 0x00000000;
+ phy_tonemask_to_tonemask10 (tonemask, &PHY_DSPSS_HP10_MASK_0);
PHY_DSPSS_HP10_FC_MASK_0 = 0x20006000;
PHY_DSPSS_HP10_FC_MASK_1 = 0x000E0000;
PHY_DSPSS_HP10_FC_MASK_2 = 0xFFF00060;
diff --git a/cesar/hal/phy/src/tonemask.c b/cesar/hal/phy/src/tonemask.c
new file mode 100644
index 0000000000..6f47d319f6
--- /dev/null
+++ b/cesar/hal/phy/src/tonemask.c
@@ -0,0 +1,91 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2013 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/phy/src/tonemask.c
+ * \brief HAL Phy tonemask tools.
+ * \ingroup hal_phy
+ */
+#include "common/std.h"
+
+#include "hal/phy/defs.h"
+#include "hal/phy/inc/tonemask.h"
+
+void
+phy_tonemask_to_ampmap (const u32 *tonemask, u32 *ampmap)
+{
+ uint i, j;
+ u32 tmw = 0, amw;
+ for (i = 0; i < PHY_TONEMAP_WORDS; i++)
+ {
+ if (i % 4 == 0)
+ tmw = *tonemask++;
+ amw = 0;
+ for (j = 0; j < 8; j++)
+ {
+ amw >>= 4;
+ if (tmw & 1)
+ amw |= 0xf0000000;
+ tmw >>= 1;
+ }
+ *ampmap++ = amw;
+ }
+}
+
+void
+phy_tonemask_to_tonemask10 (const u32 *tonemask, volatile u32 *tonemask10)
+{
+ u64 tmw;
+ u32 m10w, m10_bit;
+ uint tm_index, tm_left, m10_carrier;
+ /* Load first word. */
+ tm_index = 0;
+ tmw = tonemask[tm_index++];
+ tm_left = 32;
+ /* Insert some bits in case first carriers are aligned. */
+ tm_left += PHY_HP10_TONEMASK_NEIGHBORS;
+ tmw <<= PHY_HP10_TONEMASK_NEIGHBORS;
+ tmw |= BITS_ONES (PHY_HP10_TONEMASK_NEIGHBORS);
+ /* Discard bits which are not part of the mask 1.0. */
+ const uint discard = PHY_HP10_CARRIER_OFFSET * PHY_HP10_CARRIER_FACTOR
+ - PHY_CARRIER_OFFSET;
+ tm_left -= discard;
+ tmw >>= discard;
+ /* For each 1.0 carrier, look at the corresponding AV carrier and its
+ * neighbors. If one is masked, mask the 1.0 carrier too. */
+ m10w = 0;
+ m10_bit = 1;
+ for (m10_carrier = 0; m10_carrier < PHY_HP10_TONEMASK_WORDS * 32;
+ m10_carrier++)
+ {
+ /* Load bits if needed. */
+ if (tm_left < PHY_HP10_TONEMASK_NEIGHBORS * 2 + 1
+ + PHY_HP10_CARRIER_FACTOR)
+ {
+ if (tm_index < PHY_TONEMASK_WORDS)
+ tmw |= (u64) tonemask[tm_index++] << tm_left;
+ else
+ tmw |= (u64) BITS_ONES (32) << tm_left;
+ tm_left += 32;
+ }
+ /* If one of its neighbors is set, mask 1.0 carrier. */
+ if (tmw & BITS_ONES (PHY_HP10_TONEMASK_NEIGHBORS * 2 + 1))
+ m10w |= m10_bit;
+ m10_bit <<= 1;
+ /* If m10w full, dump to register. */
+ if (!m10_bit)
+ {
+ *tonemask10++ = m10w;
+ m10w = 0;
+ m10_bit = 1;
+ }
+ /* Advance in tonemask. */
+ tmw >>= PHY_HP10_CARRIER_FACTOR;
+ tm_left -= PHY_HP10_CARRIER_FACTOR;
+ }
+}
+
diff --git a/cesar/hal/phy/test/tonemask/Makefile b/cesar/hal/phy/test/tonemask/Makefile
new file mode 100644
index 0000000000..7fb22e824a
--- /dev/null
+++ b/cesar/hal/phy/test/tonemask/Makefile
@@ -0,0 +1,11 @@
+BASE = ../../../..
+
+INCLUDES = hal/phy/test/tonemask/override
+
+HOST_PROGRAMS = test_tonemask
+test_tonemask_SOURCES = test_tonemask.c
+test_tonemask_MODULES = lib hal/phy mac/common
+hal_phy_MODULE_SOURCES = tonemask.c
+mac_common_SOURCES = tonemask.c
+
+include $(BASE)/common/make/top.mk
diff --git a/cesar/hal/phy/test/tonemask/override/hal/phy/defs.h b/cesar/hal/phy/test/tonemask/override/hal/phy/defs.h
new file mode 100644
index 0000000000..ad9d239214
--- /dev/null
+++ b/cesar/hal/phy/test/tonemask/override/hal/phy/defs.h
@@ -0,0 +1,35 @@
+#ifndef override_hal_phy_defs_h
+#define override_hal_phy_defs_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2013 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file override/hal/phy/defs.h
+ * \brief Override HAL Phy defines.
+ * \ingroup test
+ */
+
+#include_next "hal/phy/defs.h"
+
+/* Override defines for test. */
+
+#undef PHY_CARRIER_NB
+#define PHY_CARRIER_NB test_tonemask_carrier_nb
+#undef PHY_CARRIER_OFFSET
+#define PHY_CARRIER_OFFSET test_tonemask_carrier_offset
+
+#define TEST_TONEMASK_CARRIER_NB_MAX 1408
+
+#undef PHY_TONEMASK_WORDS
+#define PHY_TONEMASK_WORDS ((TEST_TONEMASK_CARRIER_NB_MAX + 32 - 1) / 32)
+#undef PHY_TONEMAP_WORDS
+#define PHY_TONEMAP_WORDS ((TEST_TONEMASK_CARRIER_NB_MAX + 8 - 1) / 8)
+
+extern uint test_tonemask_carrier_nb;
+extern uint test_tonemask_carrier_offset;
+
+#endif /* override_hal_phy_defs_h */
diff --git a/cesar/hal/phy/test/tonemask/src/test_tonemask.c b/cesar/hal/phy/test/tonemask/src/test_tonemask.c
new file mode 100644
index 0000000000..65b7278f88
--- /dev/null
+++ b/cesar/hal/phy/test/tonemask/src/test_tonemask.c
@@ -0,0 +1,144 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2013 MStar Semiconductor
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_tonemask.c
+ * \brief Test tonemask tooks.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "hal/phy/inc/tonemask.h"
+#include "hal/phy/defs.h"
+#include "mac/common/tonemask.h"
+
+#include "lib/test.h"
+
+#include <string.h>
+
+uint test_tonemask_carrier_nb;
+uint test_tonemask_carrier_offset;
+
+void
+ampmap_test_suite (test_t t)
+{
+ test_suite_begin (t, "ampmap");
+ test_case_begin (t, "basic");
+ test_begin (t, "pattern")
+ {
+ u32 tonemask[PHY_TONEMASK_WORDS];
+ u32 ampmap[PHY_TONEMAP_WORDS];
+ memset (tonemask, 0, sizeof (tonemask));
+ memset (ampmap, 0x42, sizeof (ampmap));
+ tonemask[0] = 0xaa55f00f;
+ tonemask[PHY_TONEMASK_WORDS - 1] = 0xaa55f00f;
+ phy_tonemask_to_ampmap (tonemask, ampmap);
+ test_fail_unless (ampmap[0] == 0x0000ffff);
+ test_fail_unless (ampmap[1] == 0xffff0000);
+ test_fail_unless (ampmap[2] == 0x0f0f0f0f);
+ test_fail_unless (ampmap[3] == 0xf0f0f0f0);
+ test_fail_unless (ampmap[PHY_TONEMAP_WORDS - 4] == 0x0000ffff);
+ test_fail_unless (ampmap[PHY_TONEMAP_WORDS - 3] == 0xffff0000);
+ test_fail_unless (ampmap[PHY_TONEMAP_WORDS - 2] == 0x0f0f0f0f);
+ test_fail_unless (ampmap[PHY_TONEMAP_WORDS - 1] == 0xf0f0f0f0);
+ } test_end;
+}
+
+void
+tonemask10_test_pattern (test_t t, uint carrier_offset, uint carrier_nb,
+ uint hp10_carrier_offset, uint hp10_carrier_nb,
+ u32 tonemask_pat, u32 tonemask10_pat)
+{
+ uint i;
+ test_within (t);
+ test_tonemask_carrier_offset = carrier_offset;
+ test_tonemask_carrier_nb = carrier_nb;
+ test_fail_unless (PHY_HP10_CARRIER_OFFSET == hp10_carrier_offset);
+ test_fail_unless (PHY_HP10_CARRIER_NB == hp10_carrier_nb);
+ u32 tonemask[PHY_TONEMASK_WORDS];
+ memset (tonemask, 0xff, sizeof (tonemask));
+ tonemask[0] = tonemask_pat;
+ u32 tonemask10[PHY_HP10_TONEMASK_WORDS];
+ phy_tonemask_to_tonemask10 (tonemask, tonemask10);
+ test_fail_unless (tonemask10[0] == tonemask10_pat);
+ for (i = 1; i < PHY_HP10_TONEMASK_WORDS; i++)
+ test_fail_unless (tonemask10[i] == 0xffffffff);
+}
+
+void
+tonemask10_test_suite (test_t t)
+{
+ test_suite_begin (t, "tonemask10");
+ test_case_begin (t, "av");
+ test_begin (t, "norm")
+ {
+ test_tonemask_carrier_offset = 74;
+ test_tonemask_carrier_nb = 1155;
+ test_fail_unless (PHY_HP10_CARRIER_OFFSET == 10);
+ test_fail_unless (PHY_HP10_CARRIER_NB == 144);
+ u32 tonemask[PHY_TONEMASK_WORDS];
+ uint unmasked_nb = tonemask_default (tonemask);
+ dbg_assert (unmasked_nb == 917);
+ u32 tonemask10[PHY_HP10_TONEMASK_WORDS];
+ phy_tonemask_to_tonemask10 (tonemask, tonemask10);
+ /* From HomePlugAV norm: */
+ test_fail_unless (tonemask10[0] == 0x0c060f01);
+ test_fail_unless (tonemask10[1] == 0xc0000400);
+ test_fail_unless (tonemask10[2] == 0x000c0001);
+ test_fail_unless (tonemask10[3] == 0x0060001e);
+ test_fail_unless (tonemask10[4] == 0xffffffe0);
+ test_fail_unless (tonemask10[5] == 0xffffffff);
+ } test_end;
+ test_case_begin (t, "basic");
+ test_begin (t, "pattern aligned begin")
+ {
+ /* 80-v
+ * _____00000000000000000000000000000000_____
+ * 1-------0-------0-------0------- */
+ tonemask10_test_pattern (t, 80, 32, 10, 4, 0x00000000, 0xfffffff1);
+ } test_end;
+ test_begin (t, "pattern aligned end")
+ {
+ /* 73-v v-80
+ * _____00000000000000000000000000000000_____
+ * 0-------0-------0-------1----- */
+ tonemask10_test_pattern (t, 73, 32, 10, 4, 0x00000000, 0xfffffff8);
+ } test_end;
+ test_begin (t, "pattern unaligned")
+ {
+ /* 79-vv-80
+ * _____00000000000000000000000000000000_____
+ * 0-------0-------0-------0------- */
+ tonemask10_test_pattern (t, 79, 32, 10, 4, 0x00000000, 0xfffffff0);
+ } test_end;
+ test_begin (t, "bit patterns")
+ {
+ /* 80-v
+ * _____00000001000000001000000001000000_____
+ * 1-------1-------1-------1------- */
+ tonemask10_test_pattern (t, 80, 32, 10, 4, 0x02010080, 0xffffffff);
+ /* 79-vv-80
+ * _____00011111000111110001111100011111_____
+ * 0-------0-------0-------0------- */
+ tonemask10_test_pattern (t, 79, 32, 10, 4, 0xf8f8f8f8, 0xfffffff0);
+ /* 79-vv-80
+ * _____00011111010001110001111100111111_____
+ * 0-------1-------0-------1------- */
+ tonemask10_test_pattern (t, 79, 32, 10, 4, 0xfcf8e2f8, 0xfffffffa);
+ } test_end;
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ test_init (t, argc, argv);
+ ampmap_test_suite (t);
+ tonemask10_test_suite (t);
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
+