summaryrefslogtreecommitdiff
path: root/mac/common/tonemap.h
blob: 028f0dd79a09d7b1a5ee35f9327bcd3d1e524177 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#ifndef mac_common_tonemap_h
#define mac_common_tonemap_h
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    mac/common/tonemap.h
 * \brief   Tone maps common declarations.
 * \ingroup mac_common
 *
 * This tone maps are shared between PB Processing, Channel Access and control
 * plane.
 */
#include "hal/phy/defs.h"
#include "lib/blk.h"

/** Tonemap indexes (TMI). */
enum tonemap_index_t
{
    /** Number of possible TMI (including, the first four). */
    TONEMAP_INDEX_NB = 32,
    /** Invalid index. */
    TONEMAP_INDEX_NULL = 32,
    /** Initial state for a tonemap set. */
    TONEMAP_INDEX_INITIAL_START = 0xfd,
    /** Error state for a tonemap set. */
    TONEMAP_INDEX_INITIAL_ERROR = 0xfc,
    /** SOUND complete state for a tonemap set. */
    TONEMAP_INDEX_INITIAL_SOUND_COMPLETE = 0xf0,
    /** Unavailable interval. */
    TONEMAP_INDEX_INTERVAL_UNAVAILABLE = 0xfe,
    /** Unusable interval. */
    TONEMAP_INDEX_INTERVAL_UNUSABLE = 0xff,
    /** SOUND complete state for an interval. */
    TONEMAP_INDEX_INTERVAL_SOUND_COMPLETE = 0xf0,
};

/** Maximum number of tonemap intervals. */
#define TONEMAP_INTERVAL_NB 32

/** Maximum number of bits per symbol with the best possible tonemask and
 * modulation. */
#define TONEMAP_BITS_PER_SYMBOL_MAX (10 * PHY_CARRIER_NB)

/** Tonemaps life duration since last refresh before it becomes stale */
#define TONEMAPS_LIFE_DURATION_S 30

/** Define a tone map interval. */
struct tonemap_interval_t
{
    /** Interval end offset. */
    u16 end_offset_atu;
    /** Interval TMI, 0-31, unavailable, unusable or sound complete. */
    u8 tmi;
};
typedef struct tonemap_interval_t tonemap_interval_t;

/** Define a set of intervals. A pair of this set is defined in a tonemaps_t.
 * One is used by pbproc; The other is used by Channel estimation. */
struct tonemap_intervals_t
{
    /** Number of intervals, 0-31. */
    uint intervals_nb;
    /** Intervals. */
    tonemap_interval_t interval[TONEMAP_INTERVAL_NB];
};
typedef struct tonemap_intervals_t tonemap_intervals_t;

/** Define a tone map. */
struct tonemap_t
{
    /** Does interval rules must be strictly enforced for this tone map.  Non
     * strict can be used if phy rate at the FEC input is less than 15Mbps. */
    bool strict;
    /** Can be used in the contention period. */
    bool cpf;
    /** FEC type, 1/2 or 16/21. */
    phy_fecrate_t fecrate;
    /** Guard interval. */
    phy_gil_t gil;
    /** Computed BLE in FC format. */
    u8 ble;
    /** Block descriptors to be used with TM DMA for the first block.  The
     * others blocks are referenced by the \c next field. */
    blk_t *tmdma_desc_head;
    /** Number of bits per data symbol. */
    uint bits_per_symbol;
    /** \todo add member to speed up tone map related computations. */

    /**
     * If tonemap is used, exchange_tmi is the index of the old tonemap that must
     * be released.
     * If tonemap expires, exchange_tmi is the index of the new tonemap that has replaced this one.
     */
    uint exchange_tmi;
};
typedef struct tonemap_t tonemap_t;

/** Define a set of tone maps and channel adaptation parameters. */
struct tonemaps_t
{
    /** Maximum FL_AV, [0x07a2, 0x0fff]. */
    uint max_fl_av;
    /** RIFS for one symbol.  Use default RIFS_AV_default for zero symbols.
     * Values should be in interval [0x18, 0x7d]. */
    uint rifs_av_one_sym_tck;
    /** RIFS for two symbols. */
    uint rifs_av_two_sym_tck;
    /** RIFS for more than two symbols. */
    uint rifs_av_g2_sym_tck;
    /** Maximum tone maps the receiver can support on this channel. */
    uint max_tm;
    /** Default TMI for contention period, 0-31, start, error or sound
     * complete. */
    uint default_tmi;
    /** Use default tone map instead of sending sound in CP. */
    bool scl_cp;
    /** Use default tone map instead of sending sound in CFP. */
    bool scl_cfp;
    /** Expiration date in cyg_tick_count_t (u64), 30 seconds from the CEI reception. */
    u64 expiration_rtc_date;
    /** Defined tone maps or NULL if invalid. */
    tonemap_t *tm[TONEMAP_INDEX_NB];
    /** SOUND complete bitmap for tone maps.  If the tone map is not valid, a
     * one in the bitmap means that sound is complete for this tone map. */
    u32 tm_sound_complete_bitmap;
    /** Pointer to the valid set of intervals used by the PBProc. */
    tonemap_intervals_t *intervals;
    /** One is the set of intervals used by the PBProc.  The other is
     * modifiable by the CE.
     * It can atomically be swapped by the CE thanks to previous intervals
     * pointer. */
    tonemap_intervals_t swap_intervals[2];
};
typedef struct tonemaps_t tonemaps_t;

extern inline uint
tonemap_interval_find (const tonemaps_t *tonemaps, uint offset_atu)
{
    uint a, b, m;
    tonemap_intervals_t *intervals = tonemaps->intervals;
    /* Dichotomy search. */
    a = 0;
    b = intervals->intervals_nb;
    while (a != b)
    {
        m = (a + b) / 2;
        if (offset_atu < intervals->interval[m].end_offset_atu)
            b = m;
        else
            a = m + 1;
    }
    return a;
}

/**
 * Compute the number of bits per Physical Block.
 * \param  fecrate  FEC encoding rate
 * \param  pb_size  PB size
 * \return  the number of bits per PB
 */
extern inline uint
tonemap_bits_per_pb (phy_fecrate_t fecrate, phy_pb_size_t pb_size)
{
    uint bits;
    dbg_assert (fecrate < PHY_FEC_RATE_NONE);
    dbg_assert (pb_size < PHY_PB_SIZE_NONE);
    /* Integrate the FEC rate 1/2 ratio... */
    bits = pb_size == PHY_PB_SIZE_136 ? 136 * 8 * 2 : 520 * 8 * 2;
    /* And undo it if necessary. */
    if (fecrate != PHY_FEC_RATE_1_2)
        bits = bits / (16 * 2) * 21; /* Always divisible by (16 * 2). */
    return bits;
}

BEGIN_DECLS

/**
 * Scan the pointer list of tone map and return the non NULL tone map pointer
 * number.
 * \param  tms  Set of tone maps
 * \return  Number of valid tonemap.
 */
u8
tonemap_valid_nb (const tonemaps_t *tms);

/**
 * Allocate a tone map in 2 blk with descriptor.
 * \return  A pointer to the tone map.
 * cf wiki for tonemap description.
 */
tonemap_t *
tonemap_alloc (void);

/**
 * Release the 2 blocks
 * \param  tm  tone map to release.
 *
 */
void
tonemap_free (tonemap_t *tm);

/**
 * Release tonemap from a set of tone map and its index.
 * \param  tms  Set of tone map
 * \param  tmi  tone map index to release
 */
void
tonemap_release (tonemaps_t *tms, int tmi);

/**
 * Allocate a new set of tone map and initialize it
 * \return  A pointer to the new set of tone map.
 */
tonemaps_t *
tonemaps_alloc (void);

/**
 * Release all tonemap in the set of tonemaps, and release it.
 * \param  tms  Set of tonemaps to release.
 */
void
tonemaps_release (tonemaps_t *tms);

/**
 * Branch the first tonemap free of a set of tonemaps to the provided tonemap.
 * \param  tms Set of tonemaps
 * \param  tm  Pointer to the provided tonemap to branch.
 * \return  the index of the newly added tonemap in the set of tonemaps.
 */
int
tonemap_set_first_free (tonemaps_t *tms, tonemap_t *tm);

/**
 * Compute floating point representation of BLE for frame control field.
 * \param  bits_per_symbol  number of bits per symbol
 * \param  fecrate  FEC encoding rate
 * \param  p_pberror_uf32  32 bit fixed point PB error rate
 * \param  gil  guard interval
 * \return  encoded BLE value
 *
 * BLE encoding format: 5 bit-mantissa and 3 bit-exponent, with the mantissa
 * in the MSB.
 *
 * BLE is given by:
 *
 *  BLE = (mant + 32) * 2^(exp-4) + 2^(exp-5)
 *
 * Max value is 0b111111100 = 508 (mant = 31, exp = 7), min value is
 * 0b10.00001 ~= 2.03125 (mant = exp = 0).
 *
 * BLE largest fractional part, including rounding: 5 bits.  I.e., result from
 * converting BLE floating point notation used in frame controls to a number
 * yield at most 5 bits of fractional part.
 */
u8
tonemap_ble (uint bits_per_symbol, phy_fecrate_t fecrate, u32 p_pberror_uf32,
             phy_gil_t gil);

END_DECLS

#endif /* mac_common_tonemap_h */