extern struct l1s_state l1s;
-enum l1_sig_num {
- L1_SIG_PM, /* Power Measurement */
- L1_SIG_NB, /* Normal Burst */
-};
-
struct l1s_meas_hdr {
uint16_t snr; /* signal/noise ratio */
int16_t toa_qbit; /* time of arrival (qbits) */
int16_t freq_err; /* Frequency error in Hz */
};
-struct l1_signal {
- uint16_t signum;
- uint16_t arfcn;
- union {
- struct {
- int16_t dbm8[2];
- } pm;
- struct {
- struct l1s_meas_hdr meas[4];
- uint16_t crc;
- uint16_t fire;
- uint16_t num_biterr;
- uint8_t frame[24];
- } nb;
- };
-};
-
-typedef void (*l1s_cb_t)(struct l1_signal *sig);
-
-void l1s_set_handler(l1s_cb_t handler);
-
int16_t l1s_snr_int(uint16_t snr);
uint16_t l1s_snr_fract(uint16_t snr);
#define ANG2FREQ_SCALING (2<<15) /* 2^15 scaling factor for fx1.15 */
#define ANGLE_TO_FREQ(angle) ((int16_t)angle * BITFREQ_DIV_PI / ANG2FREQ_SCALING)
-extern l1s_cb_t l1s_cb;
-
void l1s_reset_hw(void);
void synchronize_tdma(struct l1_cell_info *cinfo);
void l1s_time_inc(struct gsm_time *time, uint32_t delta_fn);
#include <l1a_l23_interface.h>
+struct l1s_rxnb_state {
+ struct l1s_meas_hdr meas[4];
+ uint16_t crc;
+ uint16_t fire;
+ uint16_t num_biterr;
+ uint8_t frame[24]
+};
+
+static struct l1s_rxnb_state rxnb;
static int l1s_nb_resp(__unused uint8_t p1, uint8_t burst_id, uint16_t p3)
{
- static struct l1_signal _nb_sig, *sig = &_nb_sig;
uint8_t mf_task_id = p3 & 0xff;
uint8_t mf_task_flags = p3 >> 8;
struct msgb *msg;
return 0;
}
- sig->nb.meas[burst_id].toa_qbit = dsp_api.db_r->a_serv_demod[D_TOA];
- sig->nb.meas[burst_id].pm_dbm8 = dsp_api.db_r->a_serv_demod[D_PM] >> 3;
- sig->nb.meas[burst_id].freq_err =
+ rxnb.meas[burst_id].toa_qbit = dsp_api.db_r->a_serv_demod[D_TOA];
+ rxnb.meas[burst_id].pm_dbm8 = dsp_api.db_r->a_serv_demod[D_PM] >> 3;
+ rxnb.meas[burst_id].freq_err =
ANGLE_TO_FREQ(dsp_api.db_r->a_serv_demod[D_ANGLE]);
- sig->nb.meas[burst_id].snr = dsp_api.db_r->a_serv_demod[D_SNR];
+ rxnb.meas[burst_id].snr = dsp_api.db_r->a_serv_demod[D_SNR];
/* feed computed frequency error into AFC loop */
- if (sig->nb.meas[burst_id].snr > AFC_SNR_THRESHOLD)
- afc_input(sig->nb.meas[burst_id].freq_err, rf_arfcn, 1);
+ if (rxnb.meas[burst_id].snr > AFC_SNR_THRESHOLD)
+ afc_input(rxnb.meas[burst_id].freq_err, rf_arfcn, 1);
else
- afc_input(sig->nb.meas[burst_id].freq_err, rf_arfcn, 0);
+ afc_input(rxnb.meas[burst_id].freq_err, rf_arfcn, 0);
/* 4th burst, get frame data */
if (dsp_api.db_r->d_burst_d == 3) {
int32_t avg_dbm8 = 0;
uint8_t i, j;
- sig->signum = L1_SIG_NB;
- sig->nb.num_biterr = dsp_api.ndb->a_cd[2] & 0xffff;
- sig->nb.crc = ((dsp_api.ndb->a_cd[0] & 0xffff) & ((1 << B_FIRE1) | (1 << B_FIRE0))) >> B_FIRE0;
- sig->nb.fire = ((dsp_api.ndb->a_cd[0] & 0xffff) & (1 << B_FIRE1)) >> B_FIRE1;
+ rxnb.num_biterr = dsp_api.ndb->a_cd[2] & 0xffff;
+ rxnb.crc = ((dsp_api.ndb->a_cd[0] & 0xffff) & ((1 << B_FIRE1) | (1 << B_FIRE0))) >> B_FIRE0;
+ rxnb.fire = ((dsp_api.ndb->a_cd[0] & 0xffff) & (1 << B_FIRE1)) >> B_FIRE1;
/* copy actual data, skipping the information block [0,1,2] */
for (j = 0,i = 3; i < 15; i++) {
- sig->nb.frame[j++] = dsp_api.ndb->a_cd[i] & 0xFF;
- sig->nb.frame[j++] = (dsp_api.ndb->a_cd[i] >> 8) & 0xFF;
+ rxnb.frame[j++] = dsp_api.ndb->a_cd[i] & 0xFF;
+ rxnb.frame[j++] = (dsp_api.ndb->a_cd[i] >> 8) & 0xFF;
}
- /* actually issue the signal */
- if (l1s_cb)
- l1s_cb(sig);
-
/* place it in the queue for the layer2 */
msg = l1_create_l2_msg(L1CTL_DATA_IND, l1s.current_time.fn-4,
0, rf_arfcn);
/* compute average snr and rx level */
for (i = 0; i < 4; ++i) {
- avg_snr += sig->nb.meas[i].snr;
- avg_dbm8 += sig->nb.meas[i].pm_dbm8;
+ avg_snr += rxnb.meas[i].snr;
+ avg_dbm8 += rxnb.meas[i].pm_dbm8;
}
dl->snr = avg_snr / 4;
dl->rx_level = (avg_dbm8 / (8*4)) + 110;
/* copy the actual payload data */
for (i = 0; i < 23; ++i)
- di->data[i] = sig->nb.frame[i];
+ di->data[i] = rxnb.frame[i];
l1_queue_for_l2(msg);
/* clear downlink task */