summaryrefslogtreecommitdiff
path: root/cesar
diff options
context:
space:
mode:
authorNicolas Schodet2010-12-08 11:32:51 +0100
committerNicolas Schodet2010-12-08 17:57:56 +0100
commitf581af02f1d00323b5dcc81b61b9182f4249d8e7 (patch)
tree8c46d4b889c38b76319b0e0e0c94f5f205928861 /cesar
parent026615e8722544f039f7c3f9c580746a9772efc5 (diff)
cesar/hal/phy/spoc: compute new wiener carrier registers values, refs #2145
Diffstat (limited to 'cesar')
-rw-r--r--cesar/common/tests/tests2
-rw-r--r--cesar/hal/phy/spoc/Module2
-rw-r--r--cesar/hal/phy/spoc/inc/utils.h30
-rw-r--r--cesar/hal/phy/spoc/spoc.h4
-rw-r--r--cesar/hal/phy/spoc/src/spoc_regs.c20
-rw-r--r--cesar/hal/phy/spoc/src/utils.c64
-rw-r--r--cesar/hal/phy/spoc/test/Makefile14
-rw-r--r--cesar/hal/phy/spoc/test/src/spoc_coeff_check.c13
-rw-r--r--cesar/hal/phy/spoc/test/src/test_spoc.c91
-rw-r--r--cesar/hal/phy/src/phy.c7
10 files changed, 215 insertions, 32 deletions
diff --git a/cesar/common/tests/tests b/cesar/common/tests/tests
index 8a6c547d8c..b8b2a25445 100644
--- a/cesar/common/tests/tests
+++ b/cesar/common/tests/tests
@@ -477,7 +477,7 @@ region: ./obj/region
hal/phy/spoc/test:
make host.all
-spoc: ./obj/spoc_host_check_coeff
+test_spoc: ./obj/test_spoc
test_general/station/compliance:
make
diff --git a/cesar/hal/phy/spoc/Module b/cesar/hal/phy/spoc/Module
index 0a7f2b4b11..75a0c66074 100644
--- a/cesar/hal/phy/spoc/Module
+++ b/cesar/hal/phy/spoc/Module
@@ -1 +1 @@
-SOURCES := spoc.c spoc_regs.c
+SOURCES := spoc.c spoc_regs.c utils.c
diff --git a/cesar/hal/phy/spoc/inc/utils.h b/cesar/hal/phy/spoc/inc/utils.h
new file mode 100644
index 0000000000..de9de6103a
--- /dev/null
+++ b/cesar/hal/phy/spoc/inc/utils.h
@@ -0,0 +1,30 @@
+#ifndef inc_utils_h
+#define inc_utils_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/phy/spoc/inc/utils.h
+ * \brief SPOC utilities.
+ * \ingroup hal_phy
+ */
+
+BEGIN_DECLS
+
+/**
+ * Find first and last unmasked carriers.
+ * \param tonemask tonemask data
+ * \param first_unmasked will receive first unmasked carrier
+ * \param last_unmasked will receive last unmasked carrier
+ */
+void
+phy_spoc_analyse_tonemask (const u32 *tonemask, uint *first_unmasked,
+ uint *last_unmasked);
+
+END_DECLS
+
+#endif /* inc_utils_h */
diff --git a/cesar/hal/phy/spoc/spoc.h b/cesar/hal/phy/spoc/spoc.h
index 5cc7e19ce1..7288d09852 100644
--- a/cesar/hal/phy/spoc/spoc.h
+++ b/cesar/hal/phy/spoc/spoc.h
@@ -86,9 +86,11 @@ phy_spoc_compute_all (s32 rho_q30, phy_spoc_coeff_t *coeff);
* Initialise SPOC initial state.
* \param ctx phy context
* \param rho_q30 initial frequency error, Q30 format
+ * \param tonemask tonemask data
+ * \param carrier_nb number of active carriers in the given tone mask
*/
void
-phy_spoc_init (phy_t *ctx, s32 rho_q30);
+phy_spoc_init (phy_t *ctx, s32 rho_q30, const u32 *tonemask, uint carrier_nb);
/**
* Set SPOC coefficients for TX.
diff --git a/cesar/hal/phy/spoc/src/spoc_regs.c b/cesar/hal/phy/spoc/src/spoc_regs.c
index 4e56762ecd..8f12a4a1ee 100644
--- a/cesar/hal/phy/spoc/src/spoc_regs.c
+++ b/cesar/hal/phy/spoc/src/spoc_regs.c
@@ -17,18 +17,21 @@
#include "hal/phy/inc/regs.h"
#include "hal/phy/spoc/inc/defs.h"
+#include "hal/phy/spoc/inc/utils.h"
#include "hal_phy_params.h"
/**
* Set SPOC coefficients for Wiener.
* \param ctx phy context
+ * \param tonemask tonemask data
+ * \param carrier_nb number of active carriers in the given tone mask
*/
static void
-phy_spoc_wiener_set (phy_t *ctx);
+phy_spoc_wiener_set (phy_t *ctx, const u32 *tonemask, uint carrier_nb);
void
-phy_spoc_init (phy_t *ctx, s32 rho_q30)
+phy_spoc_init (phy_t *ctx, s32 rho_q30, const u32 *tonemask, uint carrier_nb)
{
/* Compute coefficients for 0 frequency error. */
phy_spoc_coeff_t coeff;
@@ -38,7 +41,7 @@ phy_spoc_init (phy_t *ctx, s32 rho_q30)
/* Set coefficients. */
phy_spoc_tx_set (ctx, &coeff);
phy_spoc_rx_set (ctx, &coeff);
- phy_spoc_wiener_set (ctx);
+ phy_spoc_wiener_set (ctx, tonemask, carrier_nb);
/* No bypass. */
PHY_DSPSS_SPOC_DEBUG_MODE = 0;
/* Channel maximum erasing. */
@@ -123,10 +126,13 @@ phy_spoc_rx_set (phy_t *ctx, phy_spoc_coeff_t *coeff)
}
static void
-phy_spoc_wiener_set (phy_t *ctx)
+phy_spoc_wiener_set (phy_t *ctx, const u32 *tonemask, uint carrier_nb)
{
uint i;
dbg_assert (ctx);
+ /* Analyse tonemask. */
+ uint first_unmasked, last_unmasked;
+ phy_spoc_analyse_tonemask (tonemask, &first_unmasked, &last_unmasked);
/* Fill registers. */
static const int wiener_real[] = PHY_PARAM_WIENER_REAL;
static const int wiener_imag[] = PHY_PARAM_WIENER_IMAG;
@@ -135,8 +141,10 @@ phy_spoc_wiener_set (phy_t *ctx)
PHY_DSPSS_SPOC_CP_PREBEGIN_n_WIENER_REAL_n[i] = wiener_real[i];
PHY_DSPSS_SPOC_CP_PREEND_n_WIENER_IMAG_n[i] = wiener_imag[i];
}
- PHY_DSPSS_SPOC_RHO_WIENER_USED_CARRIER = PHY_CARRIER_NB;
- PHY_DSPSS_SPOC_M_CENTRAL_WIENER_FIRST_CARRIER = PHY_CARRIER_OFFSET;
+ PHY_DSPSS_SPOC_RHO_WIENER_USED_CARRIER = /* See DSPSS spec. */
+ last_unmasked - first_unmasked + 21;
+ PHY_DSPSS_SPOC_M_CENTRAL_WIENER_FIRST_CARRIER = /* Idem. */
+ PHY_CARRIER_OFFSET + first_unmasked - 9;
PHY_DSPSS_SPOC_FILTER_SHIFT =
BF_FILL (PHY_DSPSS_SPOC_FILTER_SHIFT,
PHY_PARAM_WIENER_SPOC_FILTER_SHIFT);
diff --git a/cesar/hal/phy/spoc/src/utils.c b/cesar/hal/phy/spoc/src/utils.c
new file mode 100644
index 0000000000..4699fddc3f
--- /dev/null
+++ b/cesar/hal/phy/spoc/src/utils.c
@@ -0,0 +1,64 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file hal/phy/spoc/src/utils.c
+ * \brief SPOC utilities.
+ * \ingroup hal_phy
+ */
+#include "common/std.h"
+
+#include "inc/utils.h"
+#include "hal/phy/defs.h"
+
+void
+phy_spoc_analyse_tonemask (const u32 *tonemask, uint *first_unmasked,
+ uint *last_unmasked)
+{
+ uint i, j;
+ const u32 *tk;
+ u32 tkw, tkbit;
+ dbg_assert (tonemask);
+ /* Find first unmasked carrier. */
+ tk = tonemask;
+ /* Find first non full tonemask word. */
+ for (i = 0; i < PHY_CARRIER_NB / 32; i++)
+ {
+ tkw = *tk++;
+ if (tkw != 0xffffffff)
+ break;
+ }
+ dbg_assert (i < PHY_TONEMASK_WORDS / 32);
+ /* Find first zero tonemask bit. */
+ for (j = 0, tkbit = 1;
+ tkw & tkbit;
+ j++, tkbit <<= 1)
+ ;
+ dbg_assert (tkbit);
+ /* Found. */
+ *first_unmasked = i * 32 + j;
+ /* Find last unmasked carrier. */
+ tk = tonemask + PHY_TONEMASK_WORDS - 1;
+ /* Find last non full tonemask word. */
+ tkw = *tk | (PHY_CARRIER_NB % 32 ? ~BITS_ONES (PHY_CARRIER_NB % 32) : 0);
+ for (i = PHY_TONEMASK_WORDS - 1; i; i--)
+ {
+ if (tkw != 0xffffffff)
+ break;
+ tkw = *--tk;
+ }
+ dbg_assert (i != 0);
+ /* Find last zero tonemask bit. */
+ for (j = 31, tkbit = 1 << 31;
+ tkw & tkbit;
+ j--, tkbit >>= 1)
+ ;
+ dbg_assert (tkbit);
+ /* Found. */
+ *last_unmasked = i * 32 + j;
+}
+
diff --git a/cesar/hal/phy/spoc/test/Makefile b/cesar/hal/phy/spoc/test/Makefile
index c7300ed4f1..ab95f242ad 100644
--- a/cesar/hal/phy/spoc/test/Makefile
+++ b/cesar/hal/phy/spoc/test/Makefile
@@ -3,16 +3,16 @@ BASE = ../../../..
ECOS = y
TARGET = sparc
-HOST_PROGRAMS = spoc_host_check_coeff
-TARGET_PROGRAMS = spoc_target_check_coeff
+HOST_PROGRAMS = test_spoc
+TARGET_PROGRAMS = test_spoc_target
-spoc_host_check_coeff_SOURCES = spoc_coeff_check.c
-spoc_host_check_coeff_MODULES = lib hal/phy/spoc
+test_spoc_SOURCES = test_spoc.c spoc_coeff_check.c
+test_spoc_MODULES = lib hal/phy/spoc mac/common
-spoc_target_check_coeff_SOURCES = spoc_coeff_check.c
-spoc_target_check_coeff_MODULES = lib hal/arch hal/phy hal/phy/spoc
+test_spoc_target_SOURCES = test_spoc.c spoc_coeff_check.c
+test_spoc_target_MODULES = lib hal/arch hal/phy hal/phy/spoc mac/common
-hal_phy_spoc_MODULE_SOURCES = spoc.c
+hal_phy_spoc_MODULE_SOURCES = spoc.c utils.c
coeff_h = obj/inc/coeff.h
CLEAN_FILES += $(coeff_h)
diff --git a/cesar/hal/phy/spoc/test/src/spoc_coeff_check.c b/cesar/hal/phy/spoc/test/src/spoc_coeff_check.c
index 21deb2019b..00c96e8d28 100644
--- a/cesar/hal/phy/spoc/test/src/spoc_coeff_check.c
+++ b/cesar/hal/phy/spoc/test/src/spoc_coeff_check.c
@@ -117,16 +117,3 @@ test_spoc_coeff (test_t test)
}
}
-int
-main (int argc, char **argv)
-{
- test_t test;
-
- test_init (test, argc, argv);
-
- test_spoc_coeff (test);
-
- test_result (test);
- return (test_nb_failed (test) == 0 ? 0 : 1);
-}
-
diff --git a/cesar/hal/phy/spoc/test/src/test_spoc.c b/cesar/hal/phy/spoc/test/src/test_spoc.c
new file mode 100644
index 0000000000..0b6c45f4c8
--- /dev/null
+++ b/cesar/hal/phy/spoc/test/src/test_spoc.c
@@ -0,0 +1,91 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/test_spoc.c
+ * \brief SPOC module check.
+ * \ingroup test
+ */
+#include "common/std.h"
+#include "lib/test.h"
+#include "hal/phy/spoc/inc/utils.h"
+#include "mac/common/tonemask.h"
+
+#include <string.h>
+#include <stdio.h>
+
+void
+test_spoc_coeff (test_t test);
+
+static void
+test_spoc_analyse_tonemask (test_t t)
+{
+ volatile uint i, j;
+ tonemask_info_t ti;
+ uint carrier_nb;
+ uint first_unmasked, last_unmasked;
+ test_case_begin (t, "analyse_tonemask");
+ test_begin (t, "default")
+ {
+ carrier_nb = tonemask_default (ti.tonemask);
+ dbg_assert (carrier_nb == 917);
+ phy_spoc_analyse_tonemask (ti.tonemask, &first_unmasked,
+ &last_unmasked);
+ test_fail_unless (first_unmasked == 86 - PHY_CARRIER_OFFSET);
+ test_fail_unless (last_unmasked == 1143 - PHY_CARRIER_OFFSET);
+ } test_end;
+ test_begin (t, "full")
+ {
+ memset (ti.tonemask, 0, sizeof ti.tonemask);
+ carrier_nb = PHY_CARRIER_NB;
+ phy_spoc_analyse_tonemask (ti.tonemask, &first_unmasked,
+ &last_unmasked);
+ test_fail_unless (first_unmasked == 0);
+ test_fail_unless (last_unmasked == PHY_CARRIER_NB - 1);
+ } test_end;
+ for (i = 0; i < 32; i++)
+ for (j = 0; j < 32; j++)
+ {
+ char test_name[32];
+ snprintf (test_name, sizeof test_name, "begin %d end %d", i, j);
+ test_begin (t, test_name)
+ {
+ uint last_unmasked_expect;
+ memset (ti.tonemask, 0, sizeof ti.tonemask);
+ ti.tonemask[0] = ~(1u << i);
+ if (PHY_CARRIER_NB % 32 == 0 || j < PHY_CARRIER_NB % 32)
+ {
+ last_unmasked_expect = (PHY_TONEMASK_WORDS - 1) * 32 + j;
+ ti.tonemask[PHY_TONEMASK_WORDS - 1] = ~(1u << j);
+ }
+ else
+ {
+ last_unmasked_expect = (PHY_TONEMASK_WORDS - 2) * 32 + j;
+ ti.tonemask[PHY_TONEMASK_WORDS - 2] = ~(1u << j);
+ ti.tonemask[PHY_TONEMASK_WORDS - 1] = ~0u;
+ }
+ carrier_nb = 42; /* Not really used. */
+ phy_spoc_analyse_tonemask (ti.tonemask, &first_unmasked,
+ &last_unmasked);
+ test_fail_unless (first_unmasked == i);
+ test_fail_unless (last_unmasked == last_unmasked_expect);
+ } test_end;
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ test_t t;
+ test_init (t, argc, argv);
+ test_spoc_coeff (t);
+ test_suite_begin (t, "utils");
+ test_spoc_analyse_tonemask (t);
+ test_result (t);
+ return test_nb_failed (t) == 0 ? 0 : 1;
+}
+
diff --git a/cesar/hal/phy/src/phy.c b/cesar/hal/phy/src/phy.c
index f6c872033b..9a2191a535 100644
--- a/cesar/hal/phy/src/phy.c
+++ b/cesar/hal/phy/src/phy.c
@@ -630,7 +630,7 @@ phy_set_robo_param (phy_t *ctx, u32 *tonemask, uint carrier_nb)
}
static void
-phy_set_tunable_param (phy_t *ctx)
+phy_set_tunable_param (phy_t *ctx, const u32 *tonemask, uint carrier_nb)
{
uint i;
for (i = 0; i < COUNT (phy_tunable.mafadese_coef_filter_band0); i++)
@@ -639,7 +639,8 @@ phy_set_tunable_param (phy_t *ctx)
for (i = 0; i < COUNT (phy_tunable.mafadese_coef_filter_band1); i++)
PHY_DSPSS_MAFADESE_COEF_FILTER_BAND_1_n[i] =
phy_tunable.mafadese_coef_filter_band1[i];
- phy_spoc_init (ctx, phy_tunable.spoc_rho_initial_q30);
+ phy_spoc_init (ctx, phy_tunable.spoc_rho_initial_q30, tonemask,
+ carrier_nb);
}
static void
@@ -726,7 +727,7 @@ phy_set_tonemask (phy_t *ctx, u32 *tonemask, uint carrier_nb)
PHY_DSPSS_HP10_FC_MASK_1 = 0x000E0000;
PHY_DSPSS_HP10_FC_MASK_2 = 0xFFF00060;
/* Set tunable parameters. */
- phy_set_tunable_param (ctx);
+ phy_set_tunable_param (ctx, tonemask, carrier_nb);
/* Set ROBO parameters. */
phy_set_robo_param (ctx, tonemask, carrier_nb);
/* Create preamble and PRS. */