target/layer1: Implement host-driven Tx power control
authorSylvain Munaut <tnt@246tNt.com>
Wed, 22 Sep 2010 20:22:18 +0000 (22:22 +0200)
committerSylvain Munaut <tnt@246tNt.com>
Sun, 26 Sep 2010 18:05:22 +0000 (20:05 +0200)
It's up to L23 to change the parameters using the appropriate
L1CTL call.

This is a mix between Harald's version and Dieter's version of
the TX control code.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
src/target/firmware/Makefile
src/target/firmware/board/compal/rf_power.c [new file with mode: 0644]
src/target/firmware/board/gta0x/rf_power.c [new file with mode: 0644]
src/target/firmware/include/layer1/apc.h [new file with mode: 0644]
src/target/firmware/include/layer1/sync.h
src/target/firmware/layer1/Makefile
src/target/firmware/layer1/apc.c [new file with mode: 0644]
src/target/firmware/layer1/l23_api.c
src/target/firmware/layer1/prim_rach.c
src/target/firmware/layer1/prim_tx_nb.c
src/target/firmware/layer1/sync.c

index b5fcf99..56e0068 100644 (file)
@@ -15,12 +15,12 @@ calypso_COMMON_OBJS=board/common/calypso_uart.o board/common/calypso_pwl.o
 
 gta0x_COMMON_OBJS=$(calypso_COMMON_OBJS) board/common/rffe_gta0x_triband.o
 gta0x_COMMON_ENVIRONMENTS=highram
-gta0x_OBJS=$(gta0x_COMMON_OBJS) board/gta0x/init.o
+gta0x_OBJS=$(gta0x_COMMON_OBJS) board/gta0x/init.o board/gta0x/rf_power.o
 gta0x_ENVIRONMENTS=$(gta0x_COMMON_ENVIRONMENTS)
 
 # Compal Generic
 
-compal_COMMON_OBJS=$(calypso_COMMON_OBJS) board/compal/rffe_dualband.o
+compal_COMMON_OBJS=$(calypso_COMMON_OBJS) board/compal/rffe_dualband.o board/compal/rf_power.o
 compal_COMMON_ENVIRONMENTS=compalram highram
 
 compalram_LDS=board/compal/ram.lds
diff --git a/src/target/firmware/board/compal/rf_power.c b/src/target/firmware/board/compal/rf_power.c
new file mode 100644 (file)
index 0000000..71033ae
--- /dev/null
@@ -0,0 +1,62 @@
+/* Tx RF power calibration for the Compal/Motorola dualband phones */
+
+/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdint.h>
+#include <osmocore/utils.h>
+
+/* GSM900 ARFCN 33, Measurements by Steve Markgraf / May 2010 */
+const int16_t dbm2apc_gsm900[] = {
+       [0]     = 151,
+       [1]     = 152,
+       [2]     = 153,
+       [3]     = 155,
+       [4]     = 156,
+       [5]     = 158,
+       [6]     = 160,
+       [7]     = 162,
+       [8]     = 164,
+       [9]     = 167,
+       [10]    = 170,
+       [11]    = 173,
+       [12]    = 177,
+       [13]    = 182,
+       [14]    = 187,
+       [15]    = 192,
+       [16]    = 199,
+       [17]    = 206,
+       [18]    = 214,
+       [19]    = 223,
+       [20]    = 233,
+       [21]    = 244,
+       [22]    = 260,
+       [23]    = 271,
+       [24]    = 288,
+       [25]    = 307,
+       [26]    = 327,
+       [27]    = 350,
+       [28]    = 376,
+       [29]    = 407,
+       [30]    = 456,
+       [31]    = 575,
+};
+
+const int dbm2apc_gsm900_max = ARRAY_SIZE(dbm2apc_gsm900) - 1;
diff --git a/src/target/firmware/board/gta0x/rf_power.c b/src/target/firmware/board/gta0x/rf_power.c
new file mode 100644 (file)
index 0000000..645c8a3
--- /dev/null
@@ -0,0 +1,63 @@
+/* Tx RF power calibration for the FIC GTA0x phones */
+
+/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdint.h>
+#include <osmocore/utils.h>
+
+/* GSM900 ARFCN 33, Measurements by Steve Markgraf / May 2010 */
+/* FIXME those are from compal ... need real GTA calibration */
+const int16_t dbm2apc_gsm900[] = {
+       [0]     = 151,
+       [1]     = 152,
+       [2]     = 153,
+       [3]     = 155,
+       [4]     = 156,
+       [5]     = 158,
+       [6]     = 160,
+       [7]     = 162,
+       [8]     = 164,
+       [9]     = 167,
+       [10]    = 170,
+       [11]    = 173,
+       [12]    = 177,
+       [13]    = 182,
+       [14]    = 187,
+       [15]    = 192,
+       [16]    = 199,
+       [17]    = 206,
+       [18]    = 214,
+       [19]    = 223,
+       [20]    = 233,
+       [21]    = 244,
+       [22]    = 260,
+       [23]    = 271,
+       [24]    = 288,
+       [25]    = 307,
+       [26]    = 327,
+       [27]    = 350,
+       [28]    = 376,
+       [29]    = 407,
+       [30]    = 456,
+       [31]    = 575,
+};
+
+const int dbm2apc_gsm900_max = ARRAY_SIZE(dbm2apc_gsm900) - 1;
diff --git a/src/target/firmware/include/layer1/apc.h b/src/target/firmware/include/layer1/apc.h
new file mode 100644 (file)
index 0000000..3d73c23
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _L1_APC_H
+#define _L1_APC_H
+
+/* determine the AUXAPC value by the Tx Power Level */
+int16_t apc_tx_dbm2auxapc(enum gsm_band band, int8_t dbm);
+
+/* determine the AUXAPC value by the Tx Power Level */
+int16_t apc_tx_pwrlvl2auxapc(enum gsm_band band, uint8_t lvl);
+
+#endif
index da9a5da..8baf572 100644 (file)
@@ -71,7 +71,9 @@ struct l1s_state {
        /* The current TPU offset register */
        uint32_t        tpu_offset;
 
+       /* TX parameters */
        int8_t          ta;
+       uint8_t         tx_power;
 
        /* Transmit queues of pending packets for main DCCH and ACCH */
        struct llist_head tx_queue[_NUM_L1S_CHAN];
index fd0514c..ed61c16 100644 (file)
@@ -2,7 +2,7 @@
 LIBRARIES+=layer1
 layer1_DIR=layer1
 layer1_SRCS=avg.c agc.c afc.c sync.c tdma_sched.c tpu_window.c init.c l23_api.c \
-               mframe_sched.c sched_gsmtime.c async.c rfch.c
+               mframe_sched.c sched_gsmtime.c async.c rfch.c apc.c
 
 layer1_SRCS += prim_pm.c prim_rach.c prim_tx_nb.c prim_rx_nb.c prim_fbsb.c \
                prim_freq.c
diff --git a/src/target/firmware/layer1/apc.c b/src/target/firmware/layer1/apc.c
new file mode 100644 (file)
index 0000000..5cff191
--- /dev/null
@@ -0,0 +1,57 @@
+/* APC (Automatic Power Control) Implementation */
+
+/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <errno.h>
+
+#include <osmocore/utils.h>
+#include <osmocore/gsm_utils.h>
+
+#include <layer1/apc.h>
+
+/* calibration table defined in board file */
+extern const int16_t dbm2apc_gsm900[];
+extern const int dbm2apc_gsm900_max;
+
+
+/* determine the AUXAPC value by the Tx Power Level */
+int16_t apc_tx_dbm2auxapc(enum gsm_band band, int8_t dbm)
+{
+       if (dbm < 0)
+               return -ERANGE;
+
+       /* FIXME: offsets for different bands! */
+       if (dbm > dbm2apc_gsm900_max)
+               dbm = dbm2apc_gsm900_max;
+
+       return dbm2apc_gsm900[dbm];
+}
+
+/* determine the AUXAPC value by the Tx Power Level */
+int16_t apc_tx_pwrlvl2auxapc(enum gsm_band band, uint8_t lvl)
+{
+       /* convert tx power level to dBm */
+       int dbm = ms_pwr_dbm(band, lvl);
+       if (dbm < 0)
+               return dbm;
+
+       return apc_tx_dbm2auxapc(band, dbm);
+}
index 59cb49b..5882e4c 100644 (file)
@@ -266,7 +266,7 @@ static void l1ctl_rx_param_req(struct msgb *msg)
                par_req->tx_power);
 
        l1s.ta = par_req->ta;
-       // FIXME: set power
+       l1s.tx_power = par_req->tx_power;
 }
 
 /* receive a L1CTL_RACH_REQ from L23 */
index d1880e3..56cde49 100644 (file)
@@ -63,7 +63,7 @@ static int l1s_tx_rach_cmd(__unused uint8_t p1, __unused uint8_t p2, __unused ui
 
        putchart('T');
 
-       l1s_tx_apc_helper();
+       l1s_tx_apc_helper(l1s.serving_cell.arfcn);
 
        data[0] = l1s.serving_cell.bsic << 2;
        data[1] = l1s.rach.ra;
index aeb3bb1..bff104c 100644 (file)
@@ -81,8 +81,6 @@ static int l1s_tx_cmd(uint8_t p1, uint8_t burst_id, uint16_t p3)
 
        putchart('T');
 
-       l1s_tx_apc_helper();
-
        /* before sending first of the four bursts, copy data to API ram */
        if (burst_id == 0) {
                uint16_t *info_ptr = dsp_api.ndb->a_cu;
@@ -132,6 +130,8 @@ static int l1s_tx_cmd(uint8_t p1, uint8_t burst_id, uint16_t p3)
 
        rfch_get_params(&l1s.next_time, &arfcn, &tsc, &tn);
 
+       l1s_tx_apc_helper(arfcn);
+
        if (p1 == 0)
                /* DUL_DSP_TASK, one normal burst */
                dsp_load_tch_param(&l1s.next_time,
index 9dd49f6..1d2c053 100644 (file)
@@ -50,6 +50,7 @@
 #include <layer1/sync.h>
 #include <layer1/afc.h>
 #include <layer1/agc.h>
+#include <layer1/apc.h>
 #include <layer1/tdma_sched.h>
 #include <layer1/mframe_sched.h>
 #include <layer1/sched_gsmtime.h>
@@ -321,10 +322,16 @@ void l1s_dsp_abort(void)
        tdma_schedule(0, &l1s_abort_cmd, 0, 0, 0, 10);
 }
 
-void l1s_tx_apc_helper(void)
+void l1s_tx_apc_helper(uint16_t arfcn)
 {
+       int16_t auxapc;
+       enum gsm_band band;
        int i;
 
+       /* Get DAC setting */
+       band = gsm_arfcn2band(arfcn);
+       auxapc = apc_tx_pwrlvl2auxapc(band, l1s.tx_power);
+
        /* Load the ApcOffset into the DSP */
        #define  MY_OFFSET      4
        dsp_api.ndb->d_apcoff = ABB_VAL(APCOFF, (1 << 6) | MY_OFFSET) | 1; /* 2x slope for the GTA-02 ramp */
@@ -335,7 +342,7 @@ void l1s_tx_apc_helper(void)
           especially for GSM-1800. However an MS does not send below
           0dBm anyway.
        */
-       dsp_api.db_w->d_power_ctl = ABB_VAL(AUXAPC, 0xC0); /* 2 dBm pulse with offset 4 (GSM-1800) */
+       dsp_api.db_w->d_power_ctl = ABB_VAL(AUXAPC, auxapc);
 
        /* Update the ramp according to the PCL */
        for (i = 0; i < 16; i++)
@@ -354,7 +361,9 @@ static void frame_irq(__unused enum irq_nr nr)
 /* reset the layer1 as part of synchronizing to a new cell */
 void l1s_reset(void)
 {
+       /* Reset state */
        l1s.fb.mode = 0;
+       l1s.tx_power = 7; /* initial power reset */
 
        /* reset scheduler and hardware */
        sched_gsmtime_reset();