summaryrefslogtreecommitdiff
path: root/cesar/ce/src/bitloading.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/ce/src/bitloading.c')
-rw-r--r--cesar/ce/src/bitloading.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/cesar/ce/src/bitloading.c b/cesar/ce/src/bitloading.c
new file mode 100644
index 0000000000..381affaa23
--- /dev/null
+++ b/cesar/ce/src/bitloading.c
@@ -0,0 +1,215 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2008 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file ce/src/bitloading.c
+ * \brief « brief description »
+ * \ingroup « module »
+ *
+ * « long description »
+ */
+
+#include "common/std.h"
+#include "mac/common/timings.h"
+#include "ce/inc/bitloading.h"
+
+#define SET_WORST_NIBBLE(old,new,noise) do { \
+ u32 mod = bitloading_noise2mod (noise); \
+ u32 zmod = old & 0xF; \
+ /*printf ("new mod eventuel = 0x%x, ex mod = 0x%x\n", mod, zmod);*/ \
+ if (mod < zmod) \
+ { \
+ zmod = mod; \
+ ret = true; \
+ } \
+ new = (new>>4) | (zmod<<28); \
+} while (0);
+
+#define SET_TWO_NIBBLES(new,old,two_noise) do { \
+ u32 noise = two_noise & 0x0000FFFF; \
+ SET_WORST_NIBBLE(old,new,noise); \
+ old = old >> 4; \
+ noise = (two_noise & 0xFFFF0000) >> 16; \
+ SET_WORST_NIBBLE(old,new,noise); \
+ old = old >> 4; \
+} while (0);
+
+#define SET_EIGHT_NIBBLES(tm_data,two_noise_ptr) do { \
+ u32 old = tm_data; \
+ /*printf ("old = 0x%x\n", old);*/ \
+ u32 new = 0; \
+ {SET_TWO_NIBBLES(new,old,(*two_noise_ptr)); two_noise_ptr++;} \
+ {SET_TWO_NIBBLES(new,old,(*two_noise_ptr)); two_noise_ptr++;} \
+ {SET_TWO_NIBBLES(new,old,(*two_noise_ptr)); two_noise_ptr++;} \
+ {SET_TWO_NIBBLES(new,old,(*two_noise_ptr)); two_noise_ptr++;} \
+ tm_data = new; \
+ /*printf ("new = 0x%x\n", new);*/ \
+} while (0);
+
+#define SET_256_NIBBLES(noise_blk,tm_data_ptr) do { \
+ u32 b; \
+ u32 *two_noise_ptr = (u32 *) noise_blk->data; \
+ for (b=0; b<32; b++) \
+ { \
+ SET_EIGHT_NIBBLES((*tm_data_ptr),two_noise_ptr); \
+ tm_data_ptr++; \
+ } \
+} while (0);
+
+bitloading_modification_t
+bitloading_run (mac_store_t *mac_store_ctx, mpdu_measure_t *measure)
+{
+ bitloading_modification_t ret;
+ dbg_assert (mac_store_ctx);
+ dbg_assert (measure);
+ pbproc_rx_params_t *rx_params = measure->rx_params;
+ dbg_assert (rx_params);
+ sta_t *ssta = mac_store_sta_get (mac_store_ctx, rx_params->tei);
+ dbg_assert (ssta);
+ if (ssta->rx_tonemaps->default_tmi == TONEMAP_INDEX_INITIAL_START ) // no default_tonemap
+ {
+ ret = bitloading_initial_step (ssta, measure);
+ }
+ else
+ {
+ ret = bitloading_dynamic_step (ssta, measure);
+ }
+ blk_release (ssta);
+ return ret;
+}
+
+
+bitloading_modification_t
+bitloading_initial_step (sta_t *ssta, mpdu_measure_t *measure)
+{
+ dbg_assert (ssta);
+ dbg_assert (measure);
+ bitloading_modification_t ret;
+ tonemaps_t *tms = ssta->rx_tonemaps;
+ ret.stei = ssta->tei;
+ ret.changed_tonemaps = NULL;
+ {
+ if (measure->chandata_head[PHY_CHANDATA_TYPE_NRJ])
+ {
+ bitloading_worst_tonemap_compute (&ssta->rxce.tm_in_build, measure->chandata_head[PHY_CHANDATA_TYPE_NRJ]);
+ if (ssta->rxce.measurement_computed_nb >= FRAME_NB_TO_COMPUTE_IN_INITIAL_STEP)
+ {
+ tms->default_tmi = tonemap_set_first_free (tms, ssta->rxce.tm_in_build);
+ ssta->rxce.tm_in_build = NULL;
+ ret.changed_tonemaps = tms;
+ ret.new_tmi = tms->default_tmi;
+ ret.old_tmi = TONEMAP_INDEX_NULL;
+ }
+ }
+ ssta->rxce.measurement_computed_nb++;
+ }
+ if (measure->chandata_head[PHY_CHANDATA_TYPE_NRJ_SYMBOL])
+ {
+ if (bitloading_mpdu_noise_stability (measure->chandata_head[PHY_CHANDATA_TYPE_NRJ_SYMBOL]))
+ {
+ ssta->rxce.stable_ROBO_nb++;
+ }
+ else
+ {
+ ssta->rxce.unstable_ROBO_nb++;
+ }
+ }
+ return ret;
+}
+
+bitloading_modification_t
+bitloading_dynamic_step (sta_t *sta, mpdu_measure_t *measure)
+{
+ bitloading_modification_t ret;
+ dbg_assert (sta);
+ dbg_assert (measure);
+ ret.stei = sta->tei;
+ ret.changed_tonemaps = NULL;
+ ret.new_tmi = TONEMAP_INDEX_NULL;
+ ret.old_tmi = TONEMAP_INDEX_NULL;
+ if (!sta->rxce.tm_in_build) sta->rxce.tm_in_build = tonemap_alloc ();
+ sta->rxce.measurement_computed_nb++;
+ return ret;
+}
+
+bool // Has tonemap been modified?.
+bitloading_worst_tonemap_compute (tonemap_t **worst_tm, phy_chandata_t *noise_nrj)
+{
+ dbg_assert (noise_nrj);
+ bool ret = false;
+ u32 *tm_data;
+ u32 i;
+ blk_t *blk_noise = (blk_t *) noise_nrj;
+ if (!(*worst_tm)) *worst_tm = tonemap_alloc();
+ tm_data = (u32 *) (*worst_tm)->tmdma_desc_head->data;
+ bitloading_update_threshold (1, 1);
+ for (i=0; i<4; i++)
+ {
+ SET_256_NIBBLES(blk_noise, tm_data); blk_noise = blk_noise->next;
+ }
+ tm_data = (u32 *) (*worst_tm)->tmdma_desc_head->next->data;
+ u32 *two_noise = (u32 *) blk_noise->data;
+ for (i=0; i<17; i++)
+ {
+ SET_EIGHT_NIBBLES((*tm_data), two_noise);
+ tm_data++;
+ }
+ // Not really necessary but delete the tone of unused carriers created by
+ // previous computation due to 1155%8!=0...
+ tm_data--;
+ *tm_data = *tm_data | 0xFFFFF000;
+ /** Padding of last byte force to 0 */
+ *tm_data = *tm_data & 0xFFFF0FFF;
+ return ret;
+}
+
+bool // Is noise stable along the MPDU?.
+bitloading_mpdu_noise_stability (phy_chandata_t *noise_nrj_symbol)
+{
+ dbg_assert (noise_nrj_symbol);
+ // BE CAREFUL to overflow of variables (accumulation of multiplication)
+ uint i;
+ u64 sum_x_2 = 0;
+ u64 sum_x2 = 0;
+ u64 comparator;
+ u32 val;
+ phy_noise_energy_t *data = (phy_noise_energy_t *) noise_nrj_symbol->blk.data;
+ uint symbol_number = noise_nrj_symbol->size;
+ // computation : is sigma > 0.1 *lambda ?
+ // cf spec about bitloading
+ for (i=0; i< symbol_number; i++)
+ {
+ val = *(data++);
+ dbg_assert_print (val<= NOISE_MAX, "noise overflow");
+ sum_x_2 += val;
+ sum_x2 += val * val;
+ }
+ sum_x_2 = sum_x_2 * sum_x_2;
+ comparator = 100 * (symbol_number * sum_x2 - sum_x_2);
+ return (comparator <= sum_x_2);
+}
+
+void
+bitloading_threshold_init (void)
+{
+ //QPSK_THR103 = {0.21, 0.105, 0.036,
+ //0.022, 0.0056, 0.00144, 0.00037};
+ THR3[1][0] = (uint) (0.21 * UND_CODE);
+ THR3[1][1] = (uint) (0.105 * UND_CODE);
+ THR3[1][2] = (uint) (0.036 * UND_CODE);
+ THR3[1][3] = (uint) (0.022 * UND_CODE);
+ THR3[1][4] = (uint) (0.0056 * UND_CODE);
+ THR3[1][5] = (uint) (0.00144 * UND_CODE);
+ THR3[1][6] = (uint) (0.00037 * UND_CODE);
+}
+
+uint // date_modulo_BEACON_PERIOD_ATU
+bitloading_date_in_beacon_atu_get (uint mpdu_date_tck, uint beacon_date_tck)
+{
+ dbg_assert (mpdu_date_tck - beacon_date_tck <= MAC_MS_TO_TCK (40));
+ return ( MAC_TCK_TO_ATU ((uint)(mpdu_date_tck - beacon_date_tck)));
+}