summaryrefslogtreecommitdiff
path: root/cp/beacon/inc/ntb_clock_sync.h
blob: 326374fae689a502c2a1eb6b157ea238ab9bf2df (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
#ifndef cp_beacon_inc_ntb_clock_sync_h
#define cp_beacon_inc_ntb_clock_sync_h
/* Cesar project {{{
 *
 * Copyright (C) 2007 Spidcom
 *
 * <<<Licence>>>
 *
 * }}} */
/**
 * \file    cp/beacon/inc/ntb_clock_sync.h
 * \brief   25Mhz clock management and synchronization functions.
 * \ingroup cp_beacon
 */

#include "hal/phy/phy.h" /* HAL-PHY functions dedicated to NTB clock management (access to dedicated PRATIC registers) */
#include "mac/common/config.h"

#undef MANUFACTURER_TEST /* undef it for operational mode! */

// ntb Constants

#define CCO 0
#ifdef MANUFACTURER_TEST
#define STA1 1
#define STA2 2
#define smax 3 // count of stations (including the CCo)
#else
#define smax 2 // count of stations (including the CCo)
#endif

#define NTB_DEFAULT_OFFSET             0
#define NTB_DEFAULT_NUMERATOR    1000000
#define NTB_DEFAULT_DIVISOR      3000000

#define PHY_Clk_theoric 75000000 // ideal PHY clock frequency in Hz
#define STA_Clk_theoric 25000000 // ideal STA clock frequency in Hz (1/3 of PHY clock frequency)

// ntb Types

typedef enum
{
  prev, // previous
  curr, // current
  next, // next
  e_cnt
} e_ntb_histo;

typedef struct {

  unsigned long k; // k Factor value for "w" weighting constant (w = 1 / 2^k)
  unsigned long beacon[e_cnt];                                // beacon index
  unsigned long bts_ticks[e_cnt];                             // BTS (Beacon Time Stamp) = CCo NTB date in entire ticks
  double        sta_ntb_date_decticks[e_cnt];                 // LTmr = STAn NTB date in decimal ticks
  unsigned long sta_ntb_date_ticks[e_cnt];                    // LTmr = STAn NTB date in entire ticks
  double        sta_phy_date_decticks[e_cnt];                 // PHY LTmr = STA1 25Mhz PHY date (not corrected) in decimal ticks
  unsigned long sta_phy_date_ticks[e_cnt];                    // PHY LTmr = STA1 25Mhz PHY date (not corrected) in entire ticks
  double        sta_hpav_frequ_error[e_cnt];                  // FreqError
  signed long long sta_hpav_offset[e_cnt];                    // Offset calculated by formula from paragraph 5.5 of HP_AV specification
  signed long long sta_offset[e_cnt];                         // Offset of NTB STA clock relative to CCo clock
  signed long   sta_deriv_from_cco_ntb_ticks[e_cnt];          // STAn NTB date derive from CCo NTB in entire ticks
  signed long   sta_relative_deriv_from_cco_ntb_ticks[e_cnt]; // STA NTB date relative derive from CCo NTB in entire ticks
  unsigned long sta_numerator[e_cnt];                         // STAn current numerator for PHY_Clk divisor
  double        sta_clk_frequ[e_cnt];                         // STAn current STA_Clk frenquency in Hz
  unsigned long sta_predict_next_bts_ticks[e_cnt];            // Predicted value of CCo NTB date [next BTS] at next beacon (in entire ticks)
  unsigned long sta_predict_next_sta_ticks[e_cnt];            // Predicted value of STAn NTB date at next beacon if no correction (in entire ticks)
  signed long   sta_predict_error_of_next_sta_ticks[e_cnt];   // Predicted error of STAn NTB date at next beacon (compared to next BTS value) if no correction (in entire ticks)
  double        sta_clk_frequ_should_be[e_cnt];               // STAn STA clock should be adjusted to (in Hz)
  double        sta_decimal_numerator_should_be[e_cnt];       // For max. derive of 25 ticks (25 ticks = 1 ppm @ 25Mhz), STAn STA/PHY clock ratio should be adjusted to (decimal numerator)
  unsigned long sta_integer_numerator_should_be[e_cnt];       // STAn STA/PHY clock ratio should be adjusted to (pure integer numerator)
  double        sta_clk_frequ_will_be[e_cnt];                 // STAn STA clock will be adjusted to (in Hz)
  double        sta_ntb_estimated_decticks[e_cnt];            // NTB date estimation in decimal ticks
  unsigned long sta_ntb_estimated_ticks[e_cnt];               // NTB date estimation in entire ticks
  double        sta_clk_frequ_sync_ratio[e_cnt];
  //double        sta_average_deriv_from_cco_ntb_ticks[e_cnt];
  unsigned long sta_count_samples_for_average_deriv[e_cnt];

} ntb_histo_t;

typedef struct {

  phy_t            * ntb_phy_ctx;
  mac_config_t     * ntb_mac_config;

  ntb_histo_t        ntb_histo;

  unsigned long long beacon_count;

#ifdef MANUFACTURER_TEST

#define beacon_period_on_50hz_pwl   40000                     // in microseconds
#define beacon_period_on_60hz_pwl   33333                     // in microseconds
#define beacon_period               beacon_period_on_50hz_pwl // in microseconds

#define simu_duration               (60*15)                   // in seconds
#define count_of_beacons            ((simu_duration * 1000000) / beacon_period)

double        STA_Clk[smax];                                                 // NTB STA clock frequency in Hz (CCo, STA1, ..., STAn)
double        beacon_period_decimal_ticks[smax];
unsigned long beacon_period_ticks[smax];

unsigned long PHY_Clk[smax];                                                 // PHY clock frequency in Hz (CCo, STA1, ..., STAn)
unsigned long numerator[smax];                                               // numerator for PHY clock division factor (CCo, STA1, ..., STAn)
unsigned long divisor[smax];                                                 // divisor for PHY clock division factor (CCo, STA1, ..., STAn)

unsigned long current_sta;
unsigned long beacon[count_of_beacons];                                      // beacon index
signed long   sta_cco_offset_ticks[smax-1];
double        cco_ntb_date_decticks[smax-1][count_of_beacons];               // CCo NTB date in decimal ticks
unsigned long bts_ticks[smax-1][count_of_beacons];                           // BTS (Beacon Time Stamp) = CCo NTB date in entire ticks
double        sta_ntb_date_decticks[smax-1][count_of_beacons];               // STAn NTB date in decimal ticks
unsigned long sta_ntb_date_ticks[smax-1][count_of_beacons];                  // STAn NTB date in entire ticks
double        sta_phy_date_decticks[smax-1][count_of_beacons];               // PHY LTmr = STAn 25Mhz PHY date (not corrected) in decimal ticks
unsigned long sta_phy_date_ticks[smax-1][count_of_beacons];                  // PHY LTmr = STAn 25Mhz PHY date (not corrected) in entire ticks
signed long   sta_deriv_from_cco_ntb_ticks[smax-1][count_of_beacons];        // STAn NTB date derive from CCo NTB in entire ticks
signed long   sta_relative_deriv_from_cco_ntb_ticks[smax-1][count_of_beacons]; // STAn NTB date relative derive from CCo NTB in entire ticks
unsigned long sta_numerator[smax-1][count_of_beacons];                       // STAn current numerator for PHY_Clk divisor
double        sta_clk_frequ[smax-1][count_of_beacons];                       // STAn current STA_Clk frenquency in Hz
unsigned long sta_predict_next_bts_ticks[smax-1][count_of_beacons];          // Predicted value of CCo NTB date [next BTS] at next beacon (in entire ticks)
unsigned long sta_predict_next_sta_ticks[smax-1][count_of_beacons];          // Predicted value of STAn NTB date at next beacon if no correction (in entire ticks)
signed long   sta_predict_error_of_next_sta_ticks[smax-1][count_of_beacons]; // Predicted error of STAn NTB date at next beacon (compared to next BTS value) if no correction (in entire ticks)
double        sta_clk_frequ_should_be[smax-1][count_of_beacons];             // STAn STA clock should be adjusted to (in Hz)
double        sta_decimal_numerator_should_be[smax-1][count_of_beacons];     // For max. derive of 25 ticks (25 ticks = 1 ppm @ 25Mhz), STAn STA/PHY clock ratio should be adjusted to (decimal numerator)
unsigned long sta_integer_numerator_should_be[smax-1][count_of_beacons];     // STAn STA/PHY clock ratio should be adjusted to (pure integer numerator)
double        sta_clk_frequ_will_be[smax-1][count_of_beacons];               // STAn STA clock will be adjusted to (in Hz)
double        sta_clk_frequ_sync_ratio[smax-1][count_of_beacons];
#endif

} ntb_t; // ntb context data structure

BEGIN_DECLS

// ntb API functions

/*
 * Set or update NTB offset in the MAC Config.
 * \param ntb_ctx, pointer to ntb context
 * \param offset, offset between NTB date (CCo date) and NTB_STA date (station date)
 */
void ntb_update_offset_in_mac_config(ntb_t *ntb_ctx, signed long offset);

/*
 * NTB clock management module initialisation.
 * \param phy_ctx, pointer to phy context
 * \param mac_config, pointer to mac config
 * \return pointer to ntb_t ntb context data structure being allocated 
 */
ntb_t * ntb_init(phy_t *phy_ctx, mac_config_t *mac_config);

/*
 * Synchronize local STA clock by adjusting its clock divisor as needed
 * depending on
 * 
 *   - current beacon timestamp (BTS),
 *   - SYS-base local receive time of current beacon (SYS LTmr, based on 25 Mhz local clock frequency not adjusted onto CCo clock frequency),
 *   - STA-base local receive time of current beacon (STA LTmr, based on 25 Mhz local clock frequency adjusted onto CCo clock frequency).
 *
 * \param ntb_ctx, pointer to ntb context
 * \param beacon_bts, beacon time stamp
 * \param beacon_sys_ltmr, SYS local time captured when receiving beacon
 * \param beacon_sta_ltmr, STA local time captured when receiving beacon
 */
void ntb_clk_sync(ntb_t *ntb_ctx, unsigned long beacon_bts, unsigned long beacon_sys_ltmr, unsigned long beacon_sta_ltmr);

END_DECLS

#endif /* cp_beacon_inc_ntb_clock_sync_h */