summaryrefslogtreecommitdiff
path: root/cesar/ce/rx/bitloading/src/common.c
blob: 12a68f3311a8396f093da9b26e08ac95818f68b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/* Cesar project {{{
 *
 * Copyright (C) 2009 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    ce/rx/bitloading/src/common.c
 * \brief   Common transition functions
 * \ingroup ce_rx
 */
#include "common/std.h"

#include "ce/rx/bitloading/inc/initial.h"
#include "ce/rx/bitloading/inc/common.h"
#include "ce/rx/bitloading/inc/ber.h"
#include "ce/rx/cp/inc/cp.h"
#include "ce/rx/inc/trace.h"
#include "ce/debug/gpio/gpio.h"
#include "mac/common/timings.h"

#include <cyg/kernel/kapi.h>

uint ce_rx_bl_min_time_between_ce_restart_ms[2] = { 3000, 3000 };

void
ce_rx_bl_start_bl (ce_rx_t *ce_rx, sta_t *sta, tonemask_info_t *ts)
{
    /* Check parameters. */
    dbg_assert (sta);
    /* Not using ts directly. */
    /* Not using ce_rx directly. */

    CE_RX_TRACE (BL_INITIAL, sta->tei);
    ce_debug_gpio_event (CE_DEBUG_GPIO_EVENT_CE_RX_BL_WORKING, true);

    /* Compute initial tone map. */
    tonemap_t *initial_tm = ce_rx_bl_initial (ts, &ce_rx->tonemask,
                                              &sta->ce_rx_bt);

    /* Dump tone map in trace. */
    if (CONFIG_TRACE)
    {
        dbg_assert (ts);
#define OFFSET 2
        int mod_count[OFFSET + CE_MOD_COUNT];
        uint m;
        /* Initialize. */
        mod_count[0] = phy_date ();
        mod_count[1] = sta->tei;
        for (m = OFFSET; m < COUNT (mod_count); m++)
            mod_count[m] = 0;
        /* Count. */
        if (initial_tm)
        {
            TONEMAP_READ_BEGIN (initial_tm, ts->tonemask, m)
            {
                mod_count[m + OFFSET]++;
            }
            TONEMAP_READ_END;
        }
        /* Trace result. */
        CE_RX_TRACE_N (TONEMAP, mod_count, COUNT (mod_count));
#undef OFFSET
    }

    u8 tmi;
    /* Compare with ROBO. */
    if (initial_tm != NULL && ce_rx_bl_tonemap_better_than_robo (initial_tm, ts))
    {
        /* Set it. */
        tmi = tonemaps_set_first_free_tmi (sta->rx_tonemaps, initial_tm);
        /* This assert is required because this is the first time we ever
         * set a tone map in the life of this STA. So we MUST have an
         * empty tone map index available! */
        dbg_assert (tmi != 0);
        ce_rx_bl_ber_sliding_mean_update (&sta->ce_rx_bt,
                                          initial_tm->ber_target_reached);
    }
    else
    {
        ce_debug_gpio_event (CE_DEBUG_GPIO_EVENT_CE_RX_BL_ROBO_BETTER, true);
        /* TMI ROBO. */
        tmi = PHY_MOD_ROBO;
        /* Remove computed tone map. */
        if (initial_tm != NULL)
            tonemap_free (initial_tm);
        ce_rx_bl_ber_sliding_mean_update
            (&sta->ce_rx_bt, ce_rx_bl_ber_pt_robo (ts->carrier_nb));
        /* Trace it. */
        CE_RX_TRACE (INITIAL_WORSE_THAN_ROBO, sta->tei);
    }
    sta->rx_tonemaps->default_tmi = tmi;
    ce_rx_cp_send_mme_new_tone_map
        (ce_rx, sta, TONEMAP_INDEX_IS_NEGOTIATED (tmi) ? tmi : 0, 0, true);
    /* Store next time the CE can restart. */
    uint i;
    for (i = 0; i < COUNT (ce_rx_bl_min_time_between_ce_restart_ms); i++)
        sta->ce_rx_bt.next_date_min_for_restart_rtc_date[i]
            = cyg_current_time ()
            + MAC_MS_TO_TCK (ce_rx_bl_min_time_between_ce_restart_ms[i])
            / ce_rx->tck_per_rtc;
    ce_debug_gpio_event (CE_DEBUG_GPIO_EVENT_CE_RX_BL_WORKING, false);
    ce_debug_gpio_event (CE_DEBUG_GPIO_EVENT_CE_RX_BL_ROBO_BETTER, false);
}

bool
ce_rx_bl_tonemap_better_than_robo (tonemap_t *tm, tonemask_info_t *ti)
{
    /* Check parameters. */
    dbg_assert (tm);
    dbg_assert (ti);

    if (tm->bits_per_symbol
        > ti->tonemap_robo[PHY_MOD_ROBO].bits_per_symbol)
        return true;
    else
        return false;
}