summaryrefslogtreecommitdiff
path: root/mac/common/src/tonemask.c
blob: 656f6903cd5fdad3bf1f95f2f47e96562d3b079e (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
121
122
123
124
125
126
127
128
129
130
131
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    mac/common/src/tonemask.c
 * \brief   Tonemask related functions.
 * \ingroup mac_common
 */
#include "common/std.h"

#include "tonemask.h"

uint
tonemask_carrier_nb (const u8 *tonemask)
{
    uint i, j;
    uint carrier_nb = 0;
    const u8 *tk;
    u8 tkb;
    dbg_assert_ptr (tonemask);
    /* Count carriers. */
    tk = tonemask;
    for (i = 0; i < PHY_CARRIER_NB / 8; i++)
    {
        tkb = *tk++;
        for (j = 8; j; j--, tkb >>= 1)
        {
            if (tkb & 1)
                carrier_nb++;
        }
    }
    if (PHY_CARRIER_NB % 8 != 0)
    {
        tkb = *tk++;
        for (j = PHY_CARRIER_NB % 8; j; j--, tkb >>= 1)
        {
            if (tkb & 1)
                carrier_nb++;
        }
        dbg_assert (tkb == 0);
    }
    return carrier_nb;
}

void
tonemask_update (tonemask_info_t *ti)
{
    dbg_assert (ti);
    ti->carrier_nb = tonemask_carrier_nb (ti->tonemask);
    /* Only a multiple of ncopies carriers is used, see HPAV 3.4.4.1.  This is
     * QPSK. */
    static const phy_gil_t robo_gil[] = {
        PHY_GIL_417, PHY_GIL_417, PHY_GIL_567 };
    static const uint robo_nb_copies[] = { 4, 2, 5 };
    /** \todo Update ROBO mode Ppberror with real measures. */
    static const u32 robo_p_pberror[] = {
        CONST_UF32 (0.0), CONST_UF32 (0.0), CONST_UF32 (0.0) };
    phy_mod_t m;
    for (m = PHY_MOD_ROBO; m < PHY_MOD_ROBO_NB; m++)
    {
        tonemap_t *tm = &ti->tonemap_robo[m];
        tm->strict = false;
        tm->cpf = true;
        tm->fecrate = PHY_FEC_RATE_1_2;
        tm->gil = robo_gil[m];
        uint bits_per_symbol = ti->carrier_nb / robo_nb_copies[m] * 2;
        tm->ble = tonemap_ble (bits_per_symbol, PHY_FEC_RATE_1_2,
                               robo_p_pberror[m], robo_gil[m]);
        tm->tmdma_desc_head = NULL;
        tm->bits_per_symbol = bits_per_symbol;
    }
}

uint
tonemask_default (u8 *tonemask)
{
    /** HomePlug AV default tone mask carriers. */
    static const uint carriers[] =
    {
        /* 0-70 are OFF       AM broadcast band and lower   */
        /* 71-73 are OFF      Between AM and 160-meter band */
        85,   /* 74-85 are OFF      160 meter amateur band        */
        139,  /* 86-139 are ON      HomePlug carriers             */
        167,  /* 140-167 are OFF    80 meter amateur band         */
        214,  /* 168-214 are ON     HomePlug carriers             */
        225,  /* 215-225 are OFF    5 MHz amateur band            */
        282,  /* 226-282 are ON     HomePlug Carriers             */
        302,  /* 283-302 are OFF    40 meter amateur band         */
        409,  /* 303-409 are ON     HomePlug carriers             */
        419,  /* 410-419 are OFF    30 meter amateur band         */
        569,  /* 420-569 are ON     HomePlug carriers             */
        591,  /* 570-591 are OFF    20 meter amateur band         */
        736,  /* 592-736 are ON     HomePlug carriers             */
        748,  /* 737-748 are OFF    17 meter amateur band         */
        856,  /* 749-856 are ON     HomePlug carriers             */
        882,  /* 857-882 are OFF    15 meter amateur band         */
        1015, /* 883-1015 are ON    HomePlug Carriers             */
        1027, /* 1016-1027 are OFF  12 meter amateur band         */
        1143, /* 1028-1143 are ON   HomePlug Carriers             */
        1535, /* 1144-1535 are OFF  10 meter amateur band         */
    };
    /** HomePlug AV default tone mask carriers number. */
    static const uint carriers_nb = 917;
    uint i, j;
    uint dtc_idx = 0;
    dbg_assert (carriers[0] > PHY_CARRIER_OFFSET);
    uint dtc_stop = carriers[dtc_idx] - PHY_CARRIER_OFFSET;
    bool dtc_on = false;
    dbg_assert_ptr (tonemask);
    /* Slow loop, but only done at boot time. */
    for (i = 0; i < PHY_TONEMASK_SIZE; i++)
    {
        tonemask[i] = 0;
        for (j = 0; j < 8; j++)
        {
            if (i * 8 + j > dtc_stop)
            {
                dtc_on = !dtc_on;
                dtc_stop = carriers[++dtc_idx] - PHY_CARRIER_OFFSET;
            }
            if (dtc_on)
                tonemask[i] |= 1 << j;
        }
    }
    return carriers_nb;
}