summaryrefslogtreecommitdiff
path: root/cesar/hal/phy/src/rx.c
blob: 5c202a525160e6f9192c85e049a0f4525237a748 (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
/* Cesar project {{{
 *
 * Copyright (C) 2008 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    hal/phy/src/rx.c
 * \brief   HAL Phy RX functions.
 * \ingroup hal_phy
 */
#include "common/std.h"

#include "inc/context.h"
#include "inc/regs.h"

void
phy_rx_param (phy_t *ctx, phy_fc_mode_t fc_mode)
{
    dbg_assert (ctx);
    dbg_assert (fc_mode < PHY_FC_MODE_NB);
    PHY_TRACE (RX_PARAM, fc_mode);
    PHY_DSPSS_RX_PARAM = BF_FILL (PHY_DSPSS_RX_PARAM, (FC_MODE, fc_mode))
        | PHY_DSPSS_RX_PARAM__DEFAULT;
    ctx->rx_fc_mode = fc_mode;
}

void
phy_rx_activate (phy_t *ctx, bool now, u32 date, bool flag)
{
    dbg_assert (ctx);
    u32 action = flag ? PHY_PRATIC_ACTION__SEARCH_PRE
        : PHY_PRATIC_ACTION__STOP_DETECT;
    if (now)
    {
        PHY_TRACE (RX_ACTIVATE_NOW, flag);
        PHY_PRATIC_TIMER_4_CTRL = 0;
        PHY_PRATIC_IMMEDIATE_ACTION = action;
    }
    else
    {
        PHY_TRACE (RX_ACTIVATE, date, flag);
        PHY_PRATIC_TIMER_4_DATE = date;
        PHY_PRATIC_TIMER_4_CTRL = BF_SHIFT (PHY_PRATIC_TIMER_X_CTRL__VALID,
                                            action)
            | BF_MASK (PHY_PRATIC_TIMER_X_CTRL__VALID);
    }
}

void
phy_rx_prepare (phy_t *ctx, bool short_ppdu, phy_mod_t mod,
                phy_fecrate_t fecrate, phy_pb_size_t pb_size, phy_gil_t gil,
                uint tonemap_index, uint symbol_nb)
{
    dbg_assert (ctx);
    dbg_assert (short_ppdu == true
                || (short_ppdu == false
                    && mod < PHY_MOD_NONE
                    && fecrate < PHY_FEC_RATE_NONE
                    && pb_size < PHY_PB_SIZE_NONE
                    && gil < PHY_GIL_NB
                    && BF_CHECK (PHY_DSPSS_RX_PARAM__TMBI, tonemap_index)
                    && BF_CHECK (PHY_DSPSS_RESYS_PARAM__LAST_SYMB_INDEX,
                                  symbol_nb)));
    PHY_TRACE (RX_PREPARE, short_ppdu, mod, fecrate, pb_size, gil,
               tonemap_index, symbol_nb);
    /* Set RX parameters. */
    if (short_ppdu)
    {
        PHY_DSPSS_RX_PARAM = BF_FILL (PHY_DSPSS_RX_PARAM,
                                      (FC_MODE, ctx->rx_fc_mode),
                                      (LONG_PPDU, 1))
            | PHY_DSPSS_RX_PARAM__DEFAULT;
    }
    else
    {
        PHY_DSPSS_RX_PARAM =
            BF_FILL (PHY_DSPSS_RX_PARAM,
                     (PB_SIZE, pb_size),
                     (PB_RATE, fecrate),
                     (PB_MOD, mod),
                     (FC_MODE, ctx->rx_fc_mode),
                     (TMBI, tonemap_index))
            | PHY_DSPSS_RX_PARAM__DEFAULT;
    }
    /* TODO: write offset table for GIL. */
    /* Unlock RESYS. */
    PHY_DSPSS_RESYS_PARAM =
        BF_FILL (PHY_DSPSS_RESYS_PARAM,
                 (RESYS_COND, 1),
                 (RESYS_ON, 1),
                 (LAST_SYMB_INDEX, symbol_nb));
}

u32
phy_rx_fc10 (phy_t *ctx)
{
    dbg_assert (ctx);
    u32 fc10 = PHY_DSPSS_RX_FC_10;
    if ((fc10 & PHY_DSPSS_RX_FC_10__OK_MASK) == PHY_DSPSS_RX_FC_10__OK_MASK)
    {
        return BF_GET (PHY_DSPSS_RX_FC_10__FC, PHY_DSPSS_RX_FC_10);
    }
    else
    {
        return (u32) -1;
    }
}

u32
phy_rx_sysdate (phy_t *ctx)
{
    dbg_assert (ctx);
    return PHY_PRATIC_SYS_LAST_RECEIVED_FRAME_DATE
        - BF_GET (PHY_DSPSS_RESYS_DETECT_OFFSET__PREAMBLE,
                  PHY_DSPSS_RESYS_DETECT_OFFSET);
}