[layer 1] L1CTL_PARAM_REQ is introduced to change TX power and TA.
[osmocom-bb.git] / src / target / firmware / include / layer1 / sync.h
1 #ifndef _L1_SYNC_H
2 #define _L1_SYNC_H
3
4 #include <osmocore/linuxlist.h>
5 #include <osmocore/gsm_utils.h>
6 #include <layer1/tdma_sched.h>
7 #include <layer1/mframe_sched.h>
8 #include <l1a_l23_interface.h>
9
10 /* structure representing L1 sync information about a cell */
11 struct l1_cell_info {
12         /* on which ARFCN (+band) is the cell? */
13         uint16_t        arfcn;
14         /* what's the BSIC of the cell (from SCH burst decoding) */
15         uint8_t         bsic;
16         /* Combined or non-combined CCCH */
17         uint8_t         ccch_mode; /* enum ccch_mode */
18         /* whats the delta of the cells current GSM frame number
19          * compared to our current local frame number */
20         int32_t         fn_offset;
21         /* how much does the TPU need adjustment (delta) to synchronize
22          * with the cells burst */
23         uint32_t        time_alignment;
24         /* FIXME: should we also store the AFC value? */
25 };
26
27 enum l1s_chan {
28         L1S_CHAN_MAIN,
29         L1S_CHAN_SACCH,
30         _NUM_L1S_CHAN
31 };
32
33 enum l1_compl {
34         L1_COMPL_FB,
35         L1_COMPL_RACH,
36         L1_COMPL_TX_NB,
37 };
38
39 typedef void l1_compl_cb(enum l1_compl c);
40
41 #define L1S_NUM_COMPL           32
42 #define L1S_NUM_NEIGH_CELL      6
43
44 struct l1s_state {
45         struct gsm_time current_time;   /* current GSM time */
46         struct gsm_time next_time;      /* GSM time at next TMDMA irq */
47
48         /* the cell on which we are camping right now */
49         struct l1_cell_info serving_cell;
50
51         /* neighbor cell sync info */
52         struct l1_cell_info neigh_cell[L1S_NUM_NEIGH_CELL];
53
54         /* TDMA scheduler */
55         struct tdma_scheduler tdma_sched;
56
57         /* Multiframe scheduler */
58         struct mframe_scheduler mframe_sched;
59
60         /* The current TPU offset register */
61         uint32_t        tpu_offset;
62
63         int8_t          ta;
64
65         /* Transmit queues of pending packets for main DCCH and ACCH */
66         struct llist_head tx_queue[_NUM_L1S_CHAN];
67
68         /* Which L1A completions are scheduled right now */
69         uint32_t scheduled_compl;
70         /* callbacks for each of the completions */
71         l1_compl_cb *completion[L1S_NUM_COMPL];
72
73         /* Structures below are for L1-task specific parameters, used
74          * to communicate between l1-sync and l1-async (l23_api) */
75         struct {
76                 uint8_t mode;   /* FB_MODE 0/1 */
77         } fb;
78
79         struct {
80                 /* power measurement l1 task */
81                 unsigned int mode;
82                 union {
83                         struct {
84                                 uint16_t arfcn_start;
85                                 uint16_t arfcn_next;
86                                 uint16_t arfcn_end;
87                         } range;
88                 };
89                 struct msgb *msg;
90         } pm;
91
92         struct {
93                 uint8_t         ra;
94         } rach;
95
96         struct {
97                 enum {
98                         GSM_DCHAN_NONE = 0,
99                         GSM_DCHAN_SDCCH_4,
100                         GSM_DCHAN_SDCCH_8,
101                         GSM_DCHAN_TCH_H,
102                         GSM_DCHAN_TCH_F,
103                         GSM_DCHAN_UNKNOWN,
104                 } type;
105
106                 uint8_t scn;
107                 uint8_t tsc;
108                 uint8_t tn;
109                 uint8_t h;
110
111                 union {
112                         struct {
113                                 uint16_t arfcn;
114                         } h0;
115                         struct {
116                                 uint8_t hsn;
117                                 uint8_t maio;
118                                 uint8_t n;
119                                 uint16_t ma[64];
120                         } h1;
121                 };
122         } dedicated;
123 };
124
125 extern struct l1s_state l1s;
126
127 struct l1s_meas_hdr {
128         uint16_t snr;           /* signal/noise ratio */
129         int16_t toa_qbit;       /* time of arrival (qbits) */
130         int16_t pm_dbm8;        /* power level in dbm/8 */
131         int16_t freq_err;       /* Frequency error in Hz */
132 };
133
134 int16_t l1s_snr_int(uint16_t snr);
135 uint16_t l1s_snr_fract(uint16_t snr);
136
137 void l1s_dsp_abort(void);
138
139 void l1s_fb_test(uint8_t base_fn, uint8_t fb_mode);
140 void l1s_sb_test(uint8_t base_fn);
141 void l1s_pm_test(uint8_t base_fn, uint16_t arfcn);
142 void l1s_nb_test(uint8_t base_fn);
143
144 /* schedule a completion */
145 void l1s_compl_sched(enum l1_compl c);
146
147 void l1s_init(void);
148
149 /* reset the layer1 as part of synchronizing to a new cell */
150 void l1s_reset(void);
151
152 /* init.c */
153 void layer1_init(void);
154
155 /* A debug macro to print every TDMA frame */
156 #ifdef DEBUG_EVERY_TDMA
157 #define putchart(x) putchar(x)
158 #else
159 #define putchart(x)
160 #endif
161
162 /* Convert an angle in fx1.15 notatinon into Hz */
163 #define BITFREQ_DIV_2PI         43104   /* 270kHz / 2 * pi */
164 #define BITFREQ_DIV_PI          86208   /* 270kHz / pi */
165 #define ANG2FREQ_SCALING        (2<<15) /* 2^15 scaling factor for fx1.15 */
166 #define ANGLE_TO_FREQ(angle)    ((int16_t)angle * BITFREQ_DIV_PI / ANG2FREQ_SCALING)
167
168 void l1s_reset_hw(void);
169 void synchronize_tdma(struct l1_cell_info *cinfo);
170 void l1s_time_inc(struct gsm_time *time, uint32_t delta_fn);
171 void l1s_time_dump(const struct gsm_time *time);
172
173 #endif /* _L1_SYNC_H */