summaryrefslogtreecommitdiff
path: root/cesar/bsu/aclf/aclf.h
blob: b08b71194ac061cbe6924ffcc53d243375de64c4 (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
#ifndef bsu_aclf_aclf_h
#define bsu_aclf_aclf_h
/* Cesar project {{{
 *
 * Copyright (C) 2010 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    bsu/aclf/aclf.h
 * \brief   AC Line Frequency.
 * \ingroup bsu
 *
 * All functions needed to track the frequency variation of the AC Line.
 */
#include "hal/phy/phy.h"
#include "hal/timer/timer.h"
#include "mac/common/config.h"
#include "mac/common/timings.h"
#include "common/defs/homeplugAV.h"
#include "lib/stats.h"

/** Number of beacon period start date handled.
 * The value is computed to allow the CCo to compute the four next BTOs. */
#define BSU_ACLF_BPSD_NB (HPAV_BEACON_BTO_NB + 2)

/** Frequency possibility. */
enum bsu_aclf_frequency_t
{
    BSU_ACLF_FREQ_50HZ,
    BSU_ACLF_FREQ_60HZ,
    BSU_ACLF_FREQ_NB
};
typedef enum bsu_aclf_frequency_t bsu_aclf_frequency_t;

/** Conversion of the frequency to ticks. */
enum bsu_aclf_bp_t
{
    BSU_ACLF_BP_50HZ_TCK = 1000000,
    BSU_ACLF_BP_55HZ_TCK = 909090,
    BSU_ACLF_BP_60HZ_TCK = 833333
};
typedef enum bsu_aclf_bp_t bsu_aclf_bp_t;

/** The minimum value for the beacon period in ticks for 50Hz PowerLine. */
#define BSU_ACLF_50HZ_CLK_MIN_TCK \
    BSU_ACLF_BP_50HZ_TCK - BITS_ONES (HPAV_BEACON_BTO_VALID_BITS)
/** The maximum value for the beacon period in ticks for 50Hz PowerLine. */
#define BSU_ACLF_50HZ_CLK_MAX_TCK \
    BSU_ACLF_BP_50HZ_TCK + BITS_ONES (HPAV_BEACON_BTO_VALID_BITS)
/** The minimum value for the beacon period in ticks for 60Hz PowerLine. */
#define BSU_ACLF_60HZ_CLK_MIN_TCK \
    BSU_ACLF_BP_60HZ_TCK - BITS_ONES (HPAV_BEACON_BTO_VALID_BITS)
/** The maximum value for the beacon period in ticks for 60Hz PowerLine. */
#define BSU_ACLF_60HZ_CLK_MAX_TCK \
    BSU_ACLF_BP_60HZ_TCK + BITS_ONES (HPAV_BEACON_BTO_VALID_BITS)

/** ACLF PowerLine synchronisation information. */
struct bsu_aclf_pwl_sync_t
{
    /** Last power line cross date. */
    u32 cross_date;
    /** Last power line cross date estimated. */
    u32 cross_est_date;
    /** Filtered Error in ticks. */
    int w_err_tck;
    /** Cross interval between two wake ups in ticks. */
    uint cross_interval_tck;
    /** Trig PWL crossing present. */
    bool trig_present;
    /** Inform the BSU the PLL is initialised. */
    bool init;
};

/** ACLF context structure. */
struct bsu_aclf_t
{
    /** Phy context. */
    phy_t *phy;
    /** Mac configuration, */
    mac_config_t *mac_config;
    /**
     * Inform on the frequency of the PWL. Only two values are possible
     * the 50 and 60 Hz.
     */
    const bsu_aclf_frequency_t frequency;
    /**
     * Beacon period static value. This value never change it corresponds
     * to the theoretical value of the beacon period. (1 000 000 ticks
     * for the 50 Hz and 833 333 ticks for the 60Hz)
     */
    const bsu_aclf_bp_t beacon_period_theo_tck;
    /**
     * Table of the beacon period start in date. The first value of the array
     * is the beacon period start date of the current beacon period, the next
     * value is the next one and so on.
     */
    u32 bpsd [BSU_ACLF_BPSD_NB];
    /**
     * Current beacon period value of the ACLF. Use to estimate the beacon
     * period.
     */
    uint beacon_period_tck;
    /**
     * The next four beacon period offset values. Those values can be set to
     * invalid HPAV_BEACON_BTO_INVALID.
     */
    s16 bto[HPAV_BEACON_BTO_NB];
    /**
     * Power Line information synchronisation.
     */
    struct bsu_aclf_pwl_sync_t pwl_sync;
};
typedef struct bsu_aclf_t bsu_aclf_t;

BEGIN_DECLS

/**
 * Initialise the module.
 * \param  phy  the phy context.
 * \param  mac_config  the mac config structure.
 * \return  the module context pointer.
 */
bsu_aclf_t*
bsu_aclf_init (phy_t *phy, mac_config_t *mac_config);

/**
 * Uninitialise the module.
 * \param  ctx  the module context.
 */
void
bsu_aclf_uninit (bsu_aclf_t *ctx);

/**
 * Compute the frequency of the power line using the PRATIC register.
 * \param  ctx  the module context.
 *
 * It shall read the PRATIC register twice with a gap of BSU_ACLF_ZC_50. This
 * function shall update the data in the object.
 *
 * \warn If the medium is a coaxial cable, the 50Hz will be chosen.
 */
void
bsu_aclf_acl_frequency_detection (bsu_aclf_t *ctx);

/**
 * Compute the beacon period start date from the data contained in the
 * beacon.
 * \param  ctx  the module context.
 * \param  bts_date the beacon time stamp in phy_date.
 * \param  bto  the four BTO present in the beacon.
 * \param  bpsto  the beacon period start time offset.
 */
void
bsu_aclf_compute_beacon_period_start_date (bsu_aclf_t *ctx, const u32 bts_date,
                                           const s16 bto[HPAV_BEACON_BTO_NB],
                                           const u32 bpsto);

/**
 * Get the beacon period start time.
 * \param  ctx  the module context.
 * \param  bpsd  the array to store the beacon period start time values.
 * \param  nb  the number of entries desired in the array.
 *
 * nb must be at most equal to BSU_ACLF_BPSD_NB.
 */
void
bsu_aclf_beacon_period_start_date (bsu_aclf_t *ctx, u32 *bpsd, uint nb);

/**
 * Get the BTOs computed.
 * \param  ctx  the module context.
 * \param  btos  the array to store the BTO's values.
 * \param  nb  the number of entries desired in the array.
 *
 * NB must be at most equal to HPAV_BEACON_BTO_NB.
 */
void
bsu_aclf_bto (bsu_aclf_t *ctx, s16 btos[], uint nb);

/**
 * Return the next beacon period start date.
 * \param  ctx  the module context.
 */
u32
bsu_aclf_beacon_period_start_date_next (bsu_aclf_t *ctx);

/**
 * Get the current beacon period duration.
 * \param  ctx  the module context.
 * \return  the beacon period duration.
 */
u32
bsu_aclf_beacon_period_tck (bsu_aclf_t *ctx);

/**
 * Get the current beacon period duration in ATU.
 * \param  ctx  the module context.
 * \return  the beacon period duration.
 *
 * Rounded up i.e. 3906.25 == 3907
 */
u32
bsu_aclf_beacon_period_atu (bsu_aclf_t *ctx);

/**
 * Shift the date to correspond to the current date.
 * \param  ctx  the module context.
 */
void
bsu_aclf_shift_beacon_period_start_date (bsu_aclf_t *ctx);

/**
 * Compute the beacon period start date from the AC Line.
 * \param  ctx  the module context.
 */
void
bsu_aclf_ac_compute_beacon_period_start_date (bsu_aclf_t *ctx);

/**
 * Suppress the next BPSD because the it will start before the first beacon
 * period ends.
 * \param  ctx  the module context.
 */
void
bsu_aclf_bpsd_avoid_overlap (bsu_aclf_t *ctx);

/**
 * Clear all data in BSU ACLF.
 * \param  ctx  the module context.
 */
void
bsu_aclf_clear (bsu_aclf_t *ctx);

/**
 * Track the PowerLine cross date.
 * \param  ctx  the module context.
 */
void
bsu_aclf_track_powerline (bsu_aclf_t *ctx);

END_DECLS

#endif /* bsu_aclf_aclf_h */