summaryrefslogtreecommitdiff
path: root/cesar/hal/phy/phy.h
blob: 999a24c007fc0a170da977304a9f62496fc121cd (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
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
#ifndef hal_phy_phy_h
#define hal_phy_phy_h
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    hal/phy/phy.h
 * \brief   HAL Phy public interface.
 * \ingroup hal_phy
 */
#include "hal/phy/access.h"
#include "hal/phy/pbdma.h"
#include "hal/phy/spoc/forward.h"

#include "hal/phy/defs.h"

#include "config/trace.h"

/** Only include number of symbols for trace. */
#if CONFIG_TRACE
# define PHY_TRACE_SYMBOL_NB(x) , x
#else
# define PHY_TRACE_SYMBOL_NB(x)
#endif

/**
 * ACCESS CONFIRM event callback.
 * \param  user  user data
 * \return  true if a DSR is requested
 */
typedef bool (*phy_access_conf_cb_t) (void *user);

/**
 * RX FC event callback.
 * \param  user  user data
 * \param  rx_date  start of preamble date
 * \param  fc_av  frame control, or NULL if FCCS error
 * \return  true if a DSR is requested
 */
typedef bool (*phy_rx_fc_cb_t) (void *user, u32 rx_date, const u32 *fc_av);

/**
 * TX FALSE ALARM event callback.
 * \param  user  user data
 * \return  true if a DSR is requested
 */
typedef bool (*phy_tx_false_alarm_cb_t) (void *user);

/**
 * Zero-cross event callback.
 * \param  user  user data
 * \return  true if a DSR is requested
 *
 * Zero-cross event happens every 20 ms (or 16,67 ms).
 */
typedef bool (*phy_zero_cross_cb_t) (void *user, const u32 zero_cross_date);

/**
 * If a DSR was requested, this callback is called.
 * \param  user  user data
 */
typedef void (*phy_deferred_cb_t) (void *user);

/**
 * Extra timer callback.
 * \param  user  user data
 * \return  true if a DSR is requested
 */
typedef bool (*phy_extra_timer_cb_t) (void *user);

/** Preparation type. */
enum phy_prepare_type_t
{
    PHY_PREPARE_TYPE_PREAMBLE,
    PHY_PREPARE_TYPE_PRS,
    PHY_PREPARE_TYPE_NB,
};
typedef enum phy_prepare_type_t phy_prepare_type_t;

BEGIN_DECLS

/**
 * Initialise the HAL Phy.
 * \param  user_data  user data passed to any callback
 * \param  rx_fc_cb  RX FC event callback
 * \param  access_cb  ACCESS event callback
 * \param  access_conf_cb  ACCESS CONFIRM event callback
 * \param  pbdma_cb  PB DMA callback
 * \param  tx_false_alarm_cb  TX FALSE ALARM callback
 * \param  deferred_cb  DSR callback
 * \return  the newly created context
 */
phy_t *
phy_init (void *user_data, phy_rx_fc_cb_t rx_fc_cb, phy_access_cb_t access_cb,
          phy_access_conf_cb_t access_conf_cb, phy_pbdma_cb_t pbdma_cb,
          phy_tx_false_alarm_cb_t tx_false_alarm_cb, phy_deferred_cb_t deferred_cb);

/**
 * Check compatibility between software and hardware.
 * \param  ctx  phy context
 */
void
phy_check_hardware (phy_t *ctx);

/**
 * Set the tone mask and its related parameters, this is a kind of
 * initialisation second step.
 * \param  ctx  phy context
 * \param  tonemask  tonemask data
 * \param  carrier_nb  number of active carriers in the given tone mask
 *
 * This also set ROBO modes parameters, HP1.0 mask and other tone mask related
 * registers.
 */
void
phy_set_tonemask (phy_t *ctx, u32 *tonemask, uint carrier_nb);

/**
 * Reset and uninitialise the HAL Phy.
 * \param  ctx  phy context
 */
void
phy_uninit (phy_t *ctx);

/**
 * Reset the hardware to a known sane state.
 * \param  ctx  phy context
 *
 * This does not reset tone mask and related parameters.
 */
void
phy_reset (phy_t *ctx);

/**
 * Report an unexpected event for debugging purpose.
 * \param  ctx  phy context
 * \param  expected_event_mask  mask of expected events (or'ed)
 * \param  unexpected_event  unexpected event
 *
 * This is recorded for future crash analysis.
 */
void
phy_debug_unexpected (phy_t *ctx, uint expected_event_mask,
                      uint unexpected_event);

/**
 * Make the specified preparation.
 * \param  ctx  phy context
 * \param  type  preparation type
 * \param  wait  wait until preparation done
 */
void
phy_prepare (phy_t *ctx, phy_prepare_type_t type, bool wait);

/**
 * Get random seed from the medium.
 * \return  32 random bits
 */
u32
phy_seed (void);

/**
 * Ask for deferred callback to be executed again later.
 * \param  ctx  phy context
 */
void
phy_deferred_schedule (phy_t *ctx);

/**
 * Get current date.
 * \return  current date
 */
u32
phy_date (void);

/**
 * Retrieve uncorrected current date.
 * \return  current uncorrected date
 */
u32
phy_sysdate (void);

/**
 * Set the clock correction.
 * \param  ctx  phy context
 * \param  numerator_ppm  clock correction
 */
void
phy_clock_set_numerator (phy_t *ctx, uint numerator_ppm);

/**
 * Get date of last zero-cross.
 * \param  ctx  phy context
 * \return  last zero-cross date
 */
u32
phy_clock_get_zero_cross_captured_date (phy_t *ctx);

/**
 * Retrieve uncorrected date of last zero-cross.
 * \param  ctx  phy context
 * \return  last zero-cross uncorrected date
 */
u32
phy_clock_get_zero_cross_captured_sysdate (phy_t *ctx);

/**
 * Transfer tone map to hardware using the TM DMA.
 * \param  ctx  phy context
 * \param  tonemap  tonemap blocks first descriptor
 *
 * The tonemap uses two blocks.
 */
void
phy_set_tonemap (phy_t *ctx, blk_t *tonemap);

/**
 * Set frequency error in hardware.
 * \param  ctx  phy context
 * \param  sync  whether error is synchronised
 * \param  rho_q30  frequency error, see SPOC
 *
 * If error is synchronised, delta used by hardware will be fixed for preamble
 * and FC.  In the other case, hardware will try to determine it itself.
 */
void
phy_freq_error_set (phy_t *ctx, bool sync, s32 rho_q30);

/**
 * Start Homeplug 1.0 frame control encoding.
 * \param  ctx  phy context
 * \param  date  hardware date when the transmission should begin
 * \param  fc_10  Homeplug 1.0 frame control
 */
void
phy_tx_fc10 (phy_t *ctx, u32 date, u32 fc_10);

/**
 * Set TX parameters, internal function.
 * \param  ctx  phy context
 * \param  fc_mode  frame control mode
 * \param  mod_fecrate_pb_size  combined modulation type, TCC rate, PB size
 * \param  gil  guard interval for third symbol and following symbols
 * \param  symbol_nb  number of symbols, only for tracing
 */
void
phy_tx_param_ (phy_t *ctx, phy_fc_mode_t fc_mode, u32 mod_fecrate_pb_size,
               phy_gil_t gil PHY_TRACE_SYMBOL_NB (uint symbol_nb));

/**
 * Set TX parameters.
 * \param  ctx  phy context
 * \param  fc_mode  frame control mode
 * \param  mod_fecrate_pb_size  combined modulation type, TCC rate, PB size
 * \param  gil  guard interval for third symbol and following symbols
 * \param  symbol_nb  number of symbols, only used for tracing
 */
extern inline void
phy_tx_param (phy_t *ctx, phy_fc_mode_t fc_mode, u32 mod_fecrate_pb_size,
              phy_gil_t gil, uint symbol_nb)
{
    phy_tx_param_ (ctx, fc_mode, mod_fecrate_pb_size, gil
                   PHY_TRACE_SYMBOL_NB (symbol_nb));
}

/**
 * Set TX parameters, shortcut for short_ppdu.
 * \param  ctx  phy context
 * \param  fc_mode  frame control mode
 */
void
phy_tx_param_short (phy_t *ctx, phy_fc_mode_t fc_mode);

/**
 * Set TX parameters for SOUND transmission, internal function
 * \param  ctx  phy context
 * \param  fc_mode  frame control mode
 * \param  nb_pb  number of SOUND PB
 * \param  mod_fecrate_pb_size  combined modulation type, TCC rate, PB size
 * \param  gil  guard interval for third symbol and following symbols
 * \param  symbol_nb  number of symbols, only for tracing
 */
void
phy_tx_param_sound_ (phy_t *ctx, phy_fc_mode_t fc_mode, uint nb_pb,
                     u32 mod_fecrate_pb_size, phy_gil_t gil
                     PHY_TRACE_SYMBOL_NB (uint symbol_nb));

/**
 * Set TX parameters for SOUND transmission.
 * \param  ctx  phy context
 * \param  fc_mode  frame control mode
 * \param  nb_pb  number of SOUND PB
 * \param  mod_fecrate_pb_size  combined modulation type, TCC rate, PB size
 * \param  gil  guard interval for third symbol and following symbols
 * \param  symbol_nb  number of symbols, only used for tracing
 */
extern inline void
phy_tx_param_sound (phy_t *ctx, phy_fc_mode_t fc_mode, uint nb_pb,
                    u32 mod_fecrate_pb_size, phy_gil_t gil, uint symbol_nb)
{
    phy_tx_param_sound_ (ctx, fc_mode, nb_pb, mod_fecrate_pb_size, gil
                         PHY_TRACE_SYMBOL_NB (symbol_nb));
}

/**
 * Schedule a TX start, internal function.
 * \param  ctx  phy context
 * \param  date  hardware date when the transmission should begin
 * \param  want_conf__stop_tx_on_prp_lost  combo parameter, see phy_tx_frame
 */
void
phy_tx_frame_ (phy_t *ctx, u32 date, u32 want_conf__stop_tx_on_prp_lost,
               const u32 fc_av[4]);

/**
 * Schedule a TX start.
 * \param  ctx  phy context
 * \param  date  hardware date when the transmission should begin
 * \param  want_conf  request an ACCESS CONF interrupt
 * \param  stop_tx_on_prp_lost  abort TX if PRP was lost
 * \param  fc_av  frame control
 */
extern inline void
phy_tx_frame (phy_t *ctx, u32 date, bool want_conf, bool stop_tx_on_prp_lost,
              const u32 fc_av[4])
{
    phy_tx_frame_ (ctx, date, (want_conf ? PHY_WANT_CONF : 0)
                  | (stop_tx_on_prp_lost ? PHY_STOP_ON_PRP_LOST : 0), fc_av);
}

/**
 * Prepare payload TX once it has been confirmed.
 * \param  ctx  phy context
 */
void
phy_tx_prepare (phy_t *ctx);

/**
 * Cancel any programmed TX, should be called before the TX starts.
 * \param  ctx  phy context
 */
void
phy_tx_cancel (phy_t *ctx);

/**
 * Set RX parameters.
 * \param  ctx  phy context
 * \param  fc_mode  frame control mode
 *
 * The new mode is used immediately.
 */
void
phy_rx_param (phy_t *ctx, phy_fc_mode_t fc_mode);

/**
 * Activate or deactivate preamble detection.
 * \param  ctx  phy context
 * \param  now  if true, date is ignored and change is made immediately
 * \param  date  activation date
 * \param  flag  true to activate
 *
 * A pending interrupt is not cancelled.
 */
void
phy_rx_activate (phy_t *ctx, bool now, u32 date, bool flag);

/**
 * Set parameter for frame payload reception.
 * \param  ctx  phy context
 * \param  nb_pb  number of PB
 * \param  mod_fecrate_pb_size  combined modulation type, TCC rate, PB size
 * \param  gil  guard interval for third symbol and following symbols
 * \param  symbol_nb  number of expected symbols
 * \param  tcc_halfit  TCC decoder number of half iteration
 *
 * This call signals hardware that it can continue to process the incoming
 * data.
 */
void
phy_rx_prepare (phy_t *ctx, uint nb_pb, u32 mod_fecrate_pb_size,
                phy_gil_t gil, uint symbol_nb, uint tcc_halfit);

/**
 * Set parameter for short frame reception.
 * \param  ctx  phy context
 *
 * This call signals hardware that it can continue to process the incoming
 * data.  In the short PPDU case, it actually stops any further processing.
 */
void
phy_rx_prepare_short (phy_t *ctx);

/**
 * Set parameter for SOUND payload reception.
 * \param  ctx  phy context
 * \param  nb_pb  number of SOUND PB
 * \param  mod_fecrate_pb_size  combined modulation type, TCC rate, PB size
 * \param  gil  guard interval for third symbol and following symbols
 * \param  symbol_nb  number of expected symbols
 */
void
phy_rx_prepare_sound (phy_t *ctx, uint nb_pb, u32 mod_fecrate_pb_size,
                      phy_gil_t gil, uint symbol_nb);

/**
 * Retrieve Homeplug 1.0 frame control.
 * \param  ctx  phy context
 * \return  received Homeplug 1.0 frame control or (u32)-1 on CRC error
 */
u32
phy_rx_fc10 (phy_t *ctx);

/**
 * Retrieve uncorrected date of last start of preamble.
 * \param  ctx  phy context
 * \return  last start of preamble uncorrected date
 */
u32
phy_rx_sysdate (phy_t *ctx);

/**
 * Initialise extra timer callback.
 * \param  ctx  phy context
 * \param  extra_timer_user_data  user data passed to the callback
 * \param  extra_timer_cb  extra timer callback
 */
void
phy_extra_timer_init (phy_t *ctx, void *extra_timer_user_data,
                      phy_extra_timer_cb_t extra_timer_cb);

/**
 * Program the extra timer to the given date.
 * \param  ctx  phy context
 * \param  date  timer expiration date
 */
void
phy_extra_timer_program (phy_t *ctx, u32 date);

/**
 * Cancel the extra timer.
 * \param  ctx  phy context
 */
void
phy_extra_timer_cancel (phy_t *ctx);

/**
 * Initialise zero-cross callback.
 * \param  ctx  phy context
 * \param  zero_cross_cb  zero-cross callback
 */
void
phy_zero_cross_init (phy_t *ctx, phy_zero_cross_cb_t zero_cross_cb);

/**
 * Read AGC gain value from register
 * \param ctx phy context
 * \return  the AGC gain value in db.
 *
 * \warn  this value is not the exact one, an programmed offset should be
 * added to match the exact value.
 */
u32
phy_rx_agc_gain (phy_t *ctx);

/**
 * Compute SPOC coefficients.
 * \param  rho_q30  frequency error, Q30 format
 * \param  coeff  output coefficients
 */
void
phy_compute_spoc_coeff (s32 rho_q30, phy_spoc_coeff_t *coeff);

/**
 * Compute SPOC initial coefficients.
 * \param  coeff  output coefficients
 */
void
phy_compute_spoc_initial_coeff (phy_spoc_coeff_t *coeff);

END_DECLS

#endif /* hal_phy_phy_h */