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
#include <stdio.h>
#include <stdlib.h> // contains the header information or prototype of the malloc
#include <string.h>
#include "UTIL/LOG/log.h"
#include "PHY/impl_defs_lte.h"
int read_calibration_matrix(int32_t **tdd_calib_coeffs, char *calibF_fname, LTE_DL_FRAME_PARMS *frame_parms) {
FILE *calibF_fd;
char calibF_file_name[1024];
int aa,re,calibF_e ;
char* openair_dir = getenv("OPENAIR_DIR");
//printf("Number of antennas = %d\n", frame_parms->nb_antennas_tx) ;
//printf("OFDM symbol size = %d\n", frame_parms->ofdm_symbol_size) ;
if (openair_dir == NULL) {
printf("ERR: OPENAIR_DIR not defined (did you source oaienv?)\n");
exit(1);
}
sprintf(calibF_file_name, "%s/targets/PROJECTS/TDDREC/result/%s", openair_dir, calibF_fname);
calibF_fd = fopen(calibF_file_name,"r") ;
if (calibF_fd == NULL) {
printf("Warning: %s not found, running with defaults\n", calibF_file_name);
return(1);
}
printf("Loading Calibration matrix from %s\n", calibF_file_name);
for (aa=0;aa<frame_parms->nb_antennas_tx;aa++) {
for(re=0;re<frame_parms->N_RB_DL*12;re++) {
fscanf(calibF_fd, "%d", &calibF_e) ;
//printf("aa=%d, re=%d, tdd_calib[0]=%d\n", aa, re, calibF_e);
((int16_t*)(&tdd_calib_coeffs[aa][re]))[0] = calibF_e;
fscanf(calibF_fd, "%d", &calibF_e) ;
//printf("aa=%d, re=%d, tdd_calib[1]=%d\n", aa, re, calibF_e);
((int16_t*)(&tdd_calib_coeffs[aa][re]))[1] = calibF_e;
//printf("aa=%d, re=%d, tdd_calib=%d+i%d\n", aa, re, (int16_t*)(&tdd_calib_coeffs[aa][re])[0],(int16_t*)(&tdd_calib_coeffs[aa][re])[1]);
}
}
}
void estimate_DLCSI_from_ULCSI(int32_t **calib_dl_ch_estimates, int32_t **ul_ch_estimates, int32_t **tdd_calib_coeffs, LTE_DL_FRAME_PARMS *frame_parms) {
int aa,re;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
multadd_cpx_vector((int16_t*)(&tdd_calib_coeffs[aa][0]),(int16_t*)(&ul_ch_estimates[aa][0]),(int16_t*)(&calib_dl_ch_estimates[aa][0]),1,frame_parms->N_RB_DL*12,15);
/*
for (re=0; re<frame_parms->N_RB_DL*12; re++) {
((int16_t*)(&calib_dl_ch_estimates[aa][re]))[0] = (((int16_t*)(&tdd_calib_coeffs[aa][re]))[0]*((int16_t*)(&ul_ch_estimates[aa][re]))[0])>>15;
((int16_t*)(&calib_dl_ch_estimates[aa][re]))[0] -= (((int16_t*)(&tdd_calib_coeffs[aa][re]))[1]*((int16_t*)(&ul_ch_estimates[aa][re]))[1])>>15;
((int16_t*)(&calib_dl_ch_estimates[aa][re]))[1] = (((int16_t*)(&tdd_calib_coeffs[aa][re]))[0]*((int16_t*)(&ul_ch_estimates[aa][re]))[1])>>15;
((int16_t*)(&calib_dl_ch_estimates[aa][re]))[1] += (((int16_t*)(&tdd_calib_coeffs[aa][re]))[1]*((int16_t*)(&ul_ch_estimates[aa][re]))[0])>>15;
*/
/*printf("aa=%d, re=%d tdd_calib_coeffs= (%d, %d), ul_ch_estimates = (%d, %d), calib_dl_ch_estimates = (%d, %d)\n",
aa, re,
((int16_t*)&tdd_calib_coeffs[aa][re])[0], ((int16_t*)&tdd_calib_coeffs[aa][re])[1],
((int16_t*)&ul_ch_estimates[aa][re])[0], ((int16_t*)&ul_ch_estimates[aa][re])[1],
((int16_t*)&calib_dl_ch_estimates[aa][re])[0], ((int16_t*)&calib_dl_ch_estimates[aa][re])[1]);*/
//}
}
}
void compute_BF_weights(int32_t **beam_weights, int32_t **calib_dl_ch_estimates, PRECODE_TYPE_t precode_type, LTE_DL_FRAME_PARMS *frame_parms) {
int aa, re;
switch (precode_type) {
//case MRT
case MRT :
for (aa=0 ; aa<frame_parms->nb_antennas_tx ; aa++) {
for (re=0; re<frame_parms->N_RB_DL*6; re++) {
//normalisation simplied by a constent shift
((int16_t*)(&beam_weights[aa][frame_parms->first_carrier_offset+re]))[0] = ((int16_t*)(&calib_dl_ch_estimates[aa][re]))[0]<<4;
((int16_t*)(&beam_weights[aa][frame_parms->first_carrier_offset+re]))[1] = -((int16_t*)(&calib_dl_ch_estimates[aa][re]))[1]<<4;
}
for (re=frame_parms->N_RB_DL*6; re<frame_parms->N_RB_DL*12; re++) {
//normalisation simplied by a constent shift
((int16_t*)(&beam_weights[aa][re-frame_parms->N_RB_DL*6+1]))[0] = ((int16_t*)(&calib_dl_ch_estimates[aa][re]))[0]<<4;
((int16_t*)(&beam_weights[aa][re-frame_parms->N_RB_DL*6+1]))[1] = -((int16_t*)(&calib_dl_ch_estimates[aa][re]))[1]<<4;
}
}
break ;
//case ZF
case ZF :
break;
//case MMSE
case MMSE :
break;
default :
break;
}
}
//unitary test function
/*
void main() {
printf("Test Compute BF weights.\n");
int32_t **tdd_calib_coeffs, **calib_dl_ch_estimates, **ul_ch_estimates, **beam_weights;
int nb_ant, nb_freq, aa, re;
char calibF_fname[] = "calibF.m";
char BF_fname[] = "BF_weights.m";
FILE *BF_weights_fd;
nb_ant = 8;
nb_freq = 300;
// memory allocation
tdd_calib_coeffs = (int32_t **)malloc(nb_ant*sizeof(int32_t *));
calib_dl_ch_estimates = (int32_t **)malloc(nb_ant*sizeof(int32_t *));
ul_ch_estimates = (int32_t **)malloc(nb_ant*sizeof(int32_t *));
beam_weights = (int32_t **)malloc(nb_ant*sizeof(int32_t *));
for (aa=0; aa<nb_ant; aa++) {
tdd_calib_coeffs[aa] = (int32_t *)malloc(nb_freq*sizeof(int32_t));
calib_dl_ch_estimates[aa] = (int32_t *)malloc(nb_freq*sizeof(int32_t));
ul_ch_estimates[aa] = (int32_t *)malloc(nb_freq*sizeof(int32_t));
beam_weights[aa] = (int32_t *)malloc(nb_freq*sizeof(int32_t));
}
// ul channel estimation initilisation
for (aa=0; aa<nb_ant; aa++)
for (re=0; re<nb_freq; re++)
ul_ch_estimates[aa][re] = 0x7fff7fff;
// calibration coefficients loading
read_calibration_matrix(calibF_fname, nb_ant, nb_freq, tdd_calib_coeffs);
// DL calib channel estimation
estimate_DLCSI_from_ULCSI(calib_dl_ch_estimates, ul_ch_estimates, tdd_calib_coeffs, nb_ant, nb_freq);
// Beamforming weights calculation
compute_BF_weights(beam_weights, calib_dl_ch_estimates, MRT, nb_ant, nb_freq);
// writing beam_weights into a .m file
BF_weights_fd = fopen(BF_fname,"w");
for (aa=0; aa<nb_ant; aa++) {
for (re=0; re<nb_freq; re++) {
fprintf(BF_weights_fd, "%d", ((int16_t *)&beam_weights[aa][re])[0]);
fprintf(BF_weights_fd, "%s", " ");
fprintf(BF_weights_fd, "%d", ((int16_t *)&beam_weights[aa][re])[1]);
fprintf(BF_weights_fd, "%s", " ");
}
fprintf(BF_weights_fd, "\n");
}
}
*/