trxcon: use libosmocore's TDMA frame number API
Depends: (libosmocore) Ic291fd3644f34964374227a191c7045d79d77e0d Change-Id: I49a043d8483e116cf2d91820edb511846175173f
This commit is contained in:
parent
cf72753e6a
commit
3fea4de64e
|
@ -370,9 +370,9 @@ static int l1ctl_rx_fbsb_req(struct l1ctl_link *l1l, struct msgb *msg)
|
||||||
/* Start FBSB expire timer */
|
/* Start FBSB expire timer */
|
||||||
l1l->fbsb_timer.data = l1l;
|
l1l->fbsb_timer.data = l1l;
|
||||||
l1l->fbsb_timer.cb = fbsb_timer_cb;
|
l1l->fbsb_timer.cb = fbsb_timer_cb;
|
||||||
LOGP(DL1C, LOGL_INFO, "Starting FBSB timer %u ms\n", timeout * FRAME_DURATION_uS / 1000);
|
LOGP(DL1C, LOGL_INFO, "Starting FBSB timer %u ms\n", timeout * GSM_TDMA_FN_DURATION_uS / 1000);
|
||||||
osmo_timer_schedule(&l1l->fbsb_timer, 0,
|
osmo_timer_schedule(&l1l->fbsb_timer, 0,
|
||||||
timeout * FRAME_DURATION_uS);
|
timeout * GSM_TDMA_FN_DURATION_uS);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
msgb_free(msg);
|
msgb_free(msg);
|
||||||
|
|
|
@ -50,7 +50,7 @@ static void sched_clck_tick(void *data)
|
||||||
struct trx_sched *sched = (struct trx_sched *) data;
|
struct trx_sched *sched = (struct trx_sched *) data;
|
||||||
struct timespec tv_now, *tv_clock, elapsed;
|
struct timespec tv_now, *tv_clock, elapsed;
|
||||||
int64_t elapsed_us;
|
int64_t elapsed_us;
|
||||||
const struct timespec frame_duration = { .tv_sec = 0, .tv_nsec = FRAME_DURATION_uS * 1000 };
|
const struct timespec frame_duration = { .tv_sec = 0, .tv_nsec = GSM_TDMA_FN_DURATION_nS };
|
||||||
|
|
||||||
/* Check if transceiver is still alive */
|
/* Check if transceiver is still alive */
|
||||||
if (sched->fn_counter_lost++ == TRX_LOSS_FRAMES) {
|
if (sched->fn_counter_lost++ == TRX_LOSS_FRAMES) {
|
||||||
|
@ -68,7 +68,7 @@ static void sched_clck_tick(void *data)
|
||||||
elapsed_us = (elapsed.tv_sec * 1000000) + (elapsed.tv_nsec / 1000);
|
elapsed_us = (elapsed.tv_sec * 1000000) + (elapsed.tv_nsec / 1000);
|
||||||
|
|
||||||
/* If someone played with clock, or if the process stalled */
|
/* If someone played with clock, or if the process stalled */
|
||||||
if (elapsed_us > FRAME_DURATION_uS * MAX_FN_SKEW || elapsed_us < 0) {
|
if (elapsed_us > GSM_TDMA_FN_DURATION_uS * MAX_FN_SKEW || elapsed_us < 0) {
|
||||||
LOGP(DSCH, LOGL_NOTICE, "PC clock skew: "
|
LOGP(DSCH, LOGL_NOTICE, "PC clock skew: "
|
||||||
"elapsed uS %" PRId64 "\n", elapsed_us);
|
"elapsed uS %" PRId64 "\n", elapsed_us);
|
||||||
|
|
||||||
|
@ -78,11 +78,11 @@ static void sched_clck_tick(void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Schedule next FN clock */
|
/* Schedule next FN clock */
|
||||||
while (elapsed_us > FRAME_DURATION_uS / 2) {
|
while (elapsed_us > GSM_TDMA_FN_DURATION_uS / 2) {
|
||||||
timespecadd(tv_clock, &frame_duration, tv_clock);
|
timespecadd(tv_clock, &frame_duration, tv_clock);
|
||||||
elapsed_us -= FRAME_DURATION_uS;
|
elapsed_us -= GSM_TDMA_FN_DURATION_uS;
|
||||||
|
|
||||||
TDMA_FN_INC(&sched->fn_counter_proc);
|
GSM_TDMA_FN_INC(sched->fn_counter_proc);
|
||||||
|
|
||||||
/* Call frame callback */
|
/* Call frame callback */
|
||||||
if (sched->clock_cb)
|
if (sched->clock_cb)
|
||||||
|
@ -90,7 +90,7 @@ static void sched_clck_tick(void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
osmo_timer_schedule(&sched->clock_timer, 0,
|
osmo_timer_schedule(&sched->clock_timer, 0,
|
||||||
FRAME_DURATION_uS - elapsed_us);
|
GSM_TDMA_FN_DURATION_uS - elapsed_us);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sched_clck_correct(struct trx_sched *sched,
|
static void sched_clck_correct(struct trx_sched *sched,
|
||||||
|
@ -108,7 +108,7 @@ static void sched_clck_correct(struct trx_sched *sched,
|
||||||
|
|
||||||
sched->clock_timer.cb = sched_clck_tick;
|
sched->clock_timer.cb = sched_clck_tick;
|
||||||
sched->clock_timer.data = sched;
|
sched->clock_timer.data = sched;
|
||||||
osmo_timer_schedule(&sched->clock_timer, 0, FRAME_DURATION_uS);
|
osmo_timer_schedule(&sched->clock_timer, 0, GSM_TDMA_FN_DURATION_uS);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sched_clck_handle(struct trx_sched *sched, uint32_t fn)
|
int sched_clck_handle(struct trx_sched *sched, uint32_t fn)
|
||||||
|
@ -140,10 +140,10 @@ int sched_clck_handle(struct trx_sched *sched, uint32_t fn)
|
||||||
/* Calculate elapsed time / frames since last processed fn */
|
/* Calculate elapsed time / frames since last processed fn */
|
||||||
timespecsub(&tv_now, tv_clock, &elapsed);
|
timespecsub(&tv_now, tv_clock, &elapsed);
|
||||||
elapsed_us = (elapsed.tv_sec * 1000000) + (elapsed.tv_nsec / 1000);
|
elapsed_us = (elapsed.tv_sec * 1000000) + (elapsed.tv_nsec / 1000);
|
||||||
elapsed_fn = TDMA_FN_SUB(fn, sched->fn_counter_proc);
|
elapsed_fn = GSM_TDMA_FN_SUB(fn, sched->fn_counter_proc);
|
||||||
|
|
||||||
if (elapsed_fn >= 135774)
|
if (elapsed_fn >= 135774)
|
||||||
elapsed_fn -= GSM_HYPERFRAME;
|
elapsed_fn -= GSM_TDMA_HYPERFRAME;
|
||||||
|
|
||||||
/* Check for max clock skew */
|
/* Check for max clock skew */
|
||||||
if (elapsed_fn > MAX_FN_SKEW || elapsed_fn < -MAX_FN_SKEW) {
|
if (elapsed_fn > MAX_FN_SKEW || elapsed_fn < -MAX_FN_SKEW) {
|
||||||
|
@ -155,7 +155,7 @@ int sched_clck_handle(struct trx_sched *sched, uint32_t fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGP(DSCH, LOGL_INFO, "GSM clock jitter: %" PRId64 "\n",
|
LOGP(DSCH, LOGL_INFO, "GSM clock jitter: %" PRId64 "\n",
|
||||||
elapsed_fn * FRAME_DURATION_uS - elapsed_us);
|
elapsed_fn * GSM_TDMA_FN_DURATION_uS - elapsed_us);
|
||||||
|
|
||||||
/* Too many frames have been processed already */
|
/* Too many frames have been processed already */
|
||||||
if (elapsed_fn < 0) {
|
if (elapsed_fn < 0) {
|
||||||
|
@ -164,21 +164,21 @@ int sched_clck_handle(struct trx_sched *sched, uint32_t fn)
|
||||||
* Set clock to the time or last FN should
|
* Set clock to the time or last FN should
|
||||||
* have been transmitted
|
* have been transmitted
|
||||||
*/
|
*/
|
||||||
duration.tv_nsec = (0 - elapsed_fn) * FRAME_DURATION_uS * 1000;
|
duration.tv_nsec = (0 - elapsed_fn) * GSM_TDMA_FN_DURATION_nS;
|
||||||
duration.tv_sec = duration.tv_nsec / 1000000000;
|
duration.tv_sec = duration.tv_nsec / 1000000000;
|
||||||
duration.tv_nsec = duration.tv_nsec % 1000000000;
|
duration.tv_nsec = duration.tv_nsec % 1000000000;
|
||||||
timespecadd(&tv_now, &duration, tv_clock);
|
timespecadd(&tv_now, &duration, tv_clock);
|
||||||
|
|
||||||
/* Set time to the time our next FN has to be transmitted */
|
/* Set time to the time our next FN has to be transmitted */
|
||||||
osmo_timer_schedule(&sched->clock_timer, 0,
|
osmo_timer_schedule(&sched->clock_timer, 0,
|
||||||
FRAME_DURATION_uS * (1 - elapsed_fn));
|
GSM_TDMA_FN_DURATION_uS * (1 - elapsed_fn));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transmit what we still need to transmit */
|
/* Transmit what we still need to transmit */
|
||||||
while (fn != sched->fn_counter_proc) {
|
while (fn != sched->fn_counter_proc) {
|
||||||
TDMA_FN_INC(&sched->fn_counter_proc);
|
GSM_TDMA_FN_INC(sched->fn_counter_proc);
|
||||||
|
|
||||||
/* Call frame callback */
|
/* Call frame callback */
|
||||||
if (sched->clock_cb)
|
if (sched->clock_cb)
|
||||||
|
@ -187,7 +187,7 @@ int sched_clck_handle(struct trx_sched *sched, uint32_t fn)
|
||||||
|
|
||||||
/* Schedule next FN to be transmitted */
|
/* Schedule next FN to be transmitted */
|
||||||
*tv_clock = tv_now;
|
*tv_clock = tv_now;
|
||||||
osmo_timer_schedule(&sched->clock_timer, 0, FRAME_DURATION_uS);
|
osmo_timer_schedule(&sched->clock_timer, 0, GSM_TDMA_FN_DURATION_uS);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,8 +171,8 @@ uint32_t sched_tchh_block_dl_first_fn(enum trx_lchan_type chan,
|
||||||
#define BLOCK_FIRST_FN(map) \
|
#define BLOCK_FIRST_FN(map) \
|
||||||
do { \
|
do { \
|
||||||
if (map[i][ARRAY_SIZE(map[i]) - 1] == fn_mf) { \
|
if (map[i][ARRAY_SIZE(map[i]) - 1] == fn_mf) { \
|
||||||
fn_diff = TDMA_FN_DIFF(fn_mf, map[i][0]); \
|
fn_diff = GSM_TDMA_FN_DIFF(fn_mf, map[i][0]); \
|
||||||
return TDMA_FN_SUB(last_fn, fn_diff); \
|
return GSM_TDMA_FN_SUB(last_fn, fn_diff); \
|
||||||
} \
|
} \
|
||||||
} while (++i < ARRAY_SIZE(map))
|
} while (++i < ARRAY_SIZE(map))
|
||||||
|
|
||||||
|
|
|
@ -68,8 +68,7 @@ static void sched_frame_clck_cb(struct trx_sched *sched)
|
||||||
* Advance frame number, giving the transceiver more
|
* Advance frame number, giving the transceiver more
|
||||||
* time until a burst must be transmitted...
|
* time until a burst must be transmitted...
|
||||||
*/
|
*/
|
||||||
fn = TDMA_FN_SUM(sched->fn_counter_proc,
|
fn = GSM_TDMA_FN_SUM(sched->fn_counter_proc, sched->fn_counter_advance);
|
||||||
sched->fn_counter_advance);
|
|
||||||
|
|
||||||
/* Get frame from multiframe */
|
/* Get frame from multiframe */
|
||||||
offset = fn % ts->mf_layout->period;
|
offset = fn % ts->mf_layout->period;
|
||||||
|
@ -636,7 +635,7 @@ static int subst_frame_loss(struct trx_lchan_state *lchan,
|
||||||
mf = lchan->ts->mf_layout;
|
mf = lchan->ts->mf_layout;
|
||||||
|
|
||||||
/* How many frames elapsed since the last one? */
|
/* How many frames elapsed since the last one? */
|
||||||
elapsed = TDMA_FN_SUB(fn, lchan->tdma.last_proc);
|
elapsed = GSM_TDMA_FN_SUB(fn, lchan->tdma.last_proc);
|
||||||
if (elapsed > mf->period) {
|
if (elapsed > mf->period) {
|
||||||
LOGP(DSCHD, LOGL_NOTICE, "Too many (>%u) contiguous TDMA frames elapsed (%u) "
|
LOGP(DSCHD, LOGL_NOTICE, "Too many (>%u) contiguous TDMA frames elapsed (%u) "
|
||||||
"since the last processed fn=%u\n", mf->period,
|
"since the last processed fn=%u\n", mf->period,
|
||||||
|
@ -656,7 +655,7 @@ static int subst_frame_loss(struct trx_lchan_state *lchan,
|
||||||
|
|
||||||
/* Traverse from fp till the current frame */
|
/* Traverse from fp till the current frame */
|
||||||
for (i = 0; i < elapsed - 1; i++) {
|
for (i = 0; i < elapsed - 1; i++) {
|
||||||
fp = &mf->frames[TDMA_FN_INC(&fake_meas.fn) % mf->period];
|
fp = &mf->frames[GSM_TDMA_FN_INC(fake_meas.fn) % mf->period];
|
||||||
if (fp->dl_chan != lchan->type)
|
if (fp->dl_chan != lchan->type)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -4,23 +4,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
|
#include <osmocom/gsm/gsm0502.h>
|
||||||
#define FRAME_DURATION_uS 4615
|
|
||||||
|
|
||||||
#define GSM_SUPERFRAME (26 * 51)
|
|
||||||
#define GSM_HYPERFRAME (2048 * GSM_SUPERFRAME)
|
|
||||||
|
|
||||||
/* TDMA frame number arithmetics */
|
|
||||||
#define TDMA_FN_SUM(a, b) \
|
|
||||||
((a + b) % GSM_HYPERFRAME)
|
|
||||||
#define TDMA_FN_SUB(a, b) \
|
|
||||||
((a + GSM_HYPERFRAME - b) % GSM_HYPERFRAME)
|
|
||||||
#define TDMA_FN_INC(fn) \
|
|
||||||
(*fn = TDMA_FN_SUM(*fn, 1))
|
|
||||||
#define TDMA_FN_MIN(a, b) \
|
|
||||||
(a < b ? a : b)
|
|
||||||
#define TDMA_FN_DIFF(a, b) \
|
|
||||||
TDMA_FN_MIN(TDMA_FN_SUB(a, b), TDMA_FN_SUB(b, a))
|
|
||||||
|
|
||||||
enum tdma_sched_clck_state {
|
enum tdma_sched_clck_state {
|
||||||
SCH_CLCK_STATE_WAIT,
|
SCH_CLCK_STATE_WAIT,
|
||||||
|
|
Loading…
Reference in New Issue