summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2012-10-19 23:07:39 +0200
committerSylvain Munaut <tnt@246tNt.com>2013-01-02 20:44:11 +0100
commit1ccc9f88229f51fdeb4823599a304b22f4b72374 (patch)
treedb8b4dfa3c346426edc11b35871708703e5e85b8
parentf853f92e4712a629ccaa5e79b97aa9340d8d9123 (diff)
target: Add support for IQ swap when required
Operation in GSM850 band requires IQ swap because of the offset PLL used in the TRF causing spectrum reversal. Thanks to Dieter Spaar for noticing the issue and the original patch Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
-rw-r--r--src/target/firmware/board/compal/rffe_dualband.c6
-rw-r--r--src/target/firmware/board/compal_e86/rffe_dualband_e86.c6
-rw-r--r--src/target/firmware/board/gta0x/rffe_gta0x_triband.c6
-rw-r--r--src/target/firmware/board/pirelli_dpl10/rffe_dpl10_triband.c6
-rw-r--r--src/target/firmware/include/calypso/dsp.h9
-rw-r--r--src/target/firmware/include/rf/trf6151.h3
-rw-r--r--src/target/firmware/include/rffe.h3
-rw-r--r--src/target/firmware/layer1/prim_rach.c7
-rw-r--r--src/target/firmware/layer1/prim_rx_nb.c5
-rw-r--r--src/target/firmware/layer1/prim_tch.c20
-rw-r--r--src/target/firmware/layer1/prim_tx_nb.c5
-rw-r--r--src/target/firmware/rf/trf6151.c14
12 files changed, 82 insertions, 8 deletions
diff --git a/src/target/firmware/board/compal/rffe_dualband.c b/src/target/firmware/board/compal/rffe_dualband.c
index f4b7361..de16189 100644
--- a/src/target/firmware/board/compal/rffe_dualband.c
+++ b/src/target/firmware/board/compal/rffe_dualband.c
@@ -55,6 +55,12 @@ uint32_t rffe_get_tx_ports(void)
return (1 << PORT_LO) | (1 << PORT_HI);
}
+/* Returns need for IQ swap */
+int rffe_iq_swapped(uint16_t band_arfcn, int tx)
+{
+ return trf6151_iq_swapped(band_arfcn, tx);
+}
+
#define MCU_SW_TRACE 0xfffef00e
#define ARM_CONF_REG 0xfffef006
diff --git a/src/target/firmware/board/compal_e86/rffe_dualband_e86.c b/src/target/firmware/board/compal_e86/rffe_dualband_e86.c
index 25bb099..4ad85dc 100644
--- a/src/target/firmware/board/compal_e86/rffe_dualband_e86.c
+++ b/src/target/firmware/board/compal_e86/rffe_dualband_e86.c
@@ -59,6 +59,12 @@ uint32_t rffe_get_tx_ports(void)
return (1 << PORT_LO) | (1 << PORT_HI);
}
+/* Returns need for IQ swap */
+int rffe_iq_swapped(uint16_t band_arfcn, int tx)
+{
+ return trf6151_iq_swapped(band_arfcn, tx);
+}
+
#define MCU_SW_TRACE 0xfffef00e
#define ARM_CONF_REG 0xfffef006
diff --git a/src/target/firmware/board/gta0x/rffe_gta0x_triband.c b/src/target/firmware/board/gta0x/rffe_gta0x_triband.c
index f118d29..b520f65 100644
--- a/src/target/firmware/board/gta0x/rffe_gta0x_triband.c
+++ b/src/target/firmware/board/gta0x/rffe_gta0x_triband.c
@@ -84,6 +84,12 @@ uint32_t rffe_get_tx_ports(void)
return (1 << PORT_LO) | (1 << PORT_HI);
}
+/* Returns need for IQ swap */
+int rffe_iq_swapped(uint16_t band_arfcn, int tx)
+{
+ return trf6151_iq_swapped(band_arfcn, tx);
+}
+
#define MCU_SW_TRACE 0xfffef00e
#define ARM_CONF_REG 0xfffef006
diff --git a/src/target/firmware/board/pirelli_dpl10/rffe_dpl10_triband.c b/src/target/firmware/board/pirelli_dpl10/rffe_dpl10_triband.c
index d4d1342..b3ec0d4 100644
--- a/src/target/firmware/board/pirelli_dpl10/rffe_dpl10_triband.c
+++ b/src/target/firmware/board/pirelli_dpl10/rffe_dpl10_triband.c
@@ -83,6 +83,12 @@ uint32_t rffe_get_tx_ports(void)
return (1 << PORT_LO) | (1 << PORT_HI);
}
+/* Returns need for IQ swap */
+int rffe_iq_swapped(uint16_t band_arfcn, int tx)
+{
+ return trf6151_iq_swapped(band_arfcn, tx);
+}
+
#define MCU_SW_TRACE 0xfffef00e
#define ARM_CONF_REG 0xfffef006
diff --git a/src/target/firmware/include/calypso/dsp.h b/src/target/firmware/include/calypso/dsp.h
index e4801cb..4f391a7 100644
--- a/src/target/firmware/include/calypso/dsp.h
+++ b/src/target/firmware/include/calypso/dsp.h
@@ -2,6 +2,7 @@
#define _CALYPSO_DSP_H
#include <calypso/dsp_api.h>
+#include <rffe.h>
#define CAL_DSP_TGT_BB_LVL 80
@@ -38,4 +39,12 @@ void dsp_end_scenario(void);
void dsp_load_rx_task(uint16_t task, uint8_t burst_id, uint8_t tsc);
void dsp_load_tx_task(uint16_t task, uint8_t burst_id, uint8_t tsc);
+static inline uint16_t
+dsp_task_iq_swap(uint16_t dsp_task, uint16_t band_arfcn, int tx)
+{
+ if (rffe_iq_swapped(band_arfcn, tx))
+ dsp_task |= 0x8000;
+ return dsp_task;
+}
+
#endif
diff --git a/src/target/firmware/include/rf/trf6151.h b/src/target/firmware/include/rf/trf6151.h
index c1eaf3b..6a23d8a 100644
--- a/src/target/firmware/include/rf/trf6151.h
+++ b/src/target/firmware/include/rf/trf6151.h
@@ -48,4 +48,7 @@ void trf6151_tx_window(int16_t start_qbits, uint16_t arfcn);
* dBm, configure the RF Frontend with the respective gain */
void trf6151_compute_gain(int16_t exp_inp, int16_t target_bb);
+/* Need for IQ swap */
+int trf6151_iq_swapped(uint16_t band_arfcn, int tx);
+
#endif /* TRF6151_H */
diff --git a/src/target/firmware/include/rffe.h b/src/target/firmware/include/rffe.h
index 63a3a4b..02fc1fd 100644
--- a/src/target/firmware/include/rffe.h
+++ b/src/target/firmware/include/rffe.h
@@ -25,6 +25,9 @@ enum rffe_port
uint32_t rffe_get_rx_ports(void);
uint32_t rffe_get_tx_ports(void);
+/* IQ swap requirements */
+int rffe_iq_swapped(uint16_t band_arfcn, int tx);
+
/* get current gain of RF frontend (anything between antenna and baseband in dBm */
uint8_t rffe_get_gain(void);
diff --git a/src/target/firmware/layer1/prim_rach.c b/src/target/firmware/layer1/prim_rach.c
index 27e89ab..08353ef 100644
--- a/src/target/firmware/layer1/prim_rach.c
+++ b/src/target/firmware/layer1/prim_rach.c
@@ -60,6 +60,7 @@ static int l1s_tx_rach_cmd(__unused uint8_t p1, __unused uint8_t p2, __unused ui
{
int i;
uint16_t *info_ptr;
+ uint16_t arfcn;
uint8_t data[2];
putchart('T');
@@ -72,9 +73,11 @@ static int l1s_tx_rach_cmd(__unused uint8_t p1, __unused uint8_t p2, __unused ui
info_ptr = &dsp_api.ndb->d_rach;
info_ptr[0] = ((uint16_t)(data[0])) | ((uint16_t)(data[1])<<8);
- dsp_api.db_w->d_task_ra = RACH_DSP_TASK;
+ arfcn = l1s.serving_cell.arfcn;
- l1s_tx_win_ctrl(l1s.serving_cell.arfcn | ARFCN_UPLINK, L1_TXWIN_AB, 0, 3);
+ dsp_api.db_w->d_task_ra = dsp_task_iq_swap(RACH_DSP_TASK, arfcn, 1);
+
+ l1s_tx_win_ctrl(arfcn | ARFCN_UPLINK, L1_TXWIN_AB, 0, 3);
return 0;
}
diff --git a/src/target/firmware/layer1/prim_rx_nb.c b/src/target/firmware/layer1/prim_rx_nb.c
index ade23a0..38c7b53 100644
--- a/src/target/firmware/layer1/prim_rx_nb.c
+++ b/src/target/firmware/layer1/prim_rx_nb.c
@@ -199,7 +199,10 @@ static int l1s_nb_cmd(__unused uint8_t p1, uint8_t burst_id,
dsp_load_tch_param(&l1s.next_time,
SIG_ONLY_MODE, SDCCH_4, 0, 0, 0, tn);
- dsp_load_rx_task(ALLC_DSP_TASK, burst_id, tsc);
+ dsp_load_rx_task(
+ dsp_task_iq_swap(ALLC_DSP_TASK, arfcn, 0),
+ burst_id, tsc
+ );
l1s_rx_win_ctrl(arfcn, L1_RXWIN_NB, 0);
diff --git a/src/target/firmware/layer1/prim_tch.c b/src/target/firmware/layer1/prim_tch.c
index a26c58e..a0a03b8 100644
--- a/src/target/firmware/layer1/prim_tch.c
+++ b/src/target/firmware/layer1/prim_tch.c
@@ -475,10 +475,16 @@ skip_tx_traffic:
0, sync, tn
);
- dsp_load_rx_task(TCHT_DSP_TASK, 0, tsc); /* burst_id unused for TCH */
+ dsp_load_rx_task(
+ dsp_task_iq_swap(TCHT_DSP_TASK, arfcn, 0),
+ 0, tsc /* burst_id unused for TCH */
+ );
l1s_rx_win_ctrl(arfcn, L1_RXWIN_NB, 0);
- dsp_load_tx_task(TCHT_DSP_TASK, 0, tsc); /* burst_id unused for TCH */
+ dsp_load_tx_task(
+ dsp_task_iq_swap(TCHT_DSP_TASK, arfcn, 1),
+ 0, tsc /* burst_id unused for TCH */
+ );
l1s_tx_win_ctrl(arfcn | ARFCN_UPLINK, L1_TXWIN_NB, 0, 3);
return 0;
@@ -734,10 +740,16 @@ static int l1s_tch_a_cmd(__unused uint8_t p1, __unused uint8_t p2, uint16_t p3)
0, 0, tn
);
- dsp_load_rx_task(TCHA_DSP_TASK, 0, tsc); /* burst_id unused for TCHA */
+ dsp_load_rx_task(
+ dsp_task_iq_swap(TCHA_DSP_TASK, arfcn, 0),
+ 0, tsc /* burst_id unused for TCHA */
+ );
l1s_rx_win_ctrl(arfcn, L1_RXWIN_NB, 0);
- dsp_load_tx_task(TCHA_DSP_TASK, 0, tsc); /* burst_id unused for TCHA */
+ dsp_load_tx_task(
+ dsp_task_iq_swap(TCHA_DSP_TASK, arfcn, 1),
+ 0, tsc /* burst_id unused for TCHA */
+ );
l1s_tx_win_ctrl(arfcn | ARFCN_UPLINK, L1_TXWIN_NB, 0, 3);
return 0;
diff --git a/src/target/firmware/layer1/prim_tx_nb.c b/src/target/firmware/layer1/prim_tx_nb.c
index df13c75..71b32eb 100644
--- a/src/target/firmware/layer1/prim_tx_nb.c
+++ b/src/target/firmware/layer1/prim_tx_nb.c
@@ -121,7 +121,10 @@ static int l1s_tx_cmd(uint8_t p1, uint8_t burst_id, uint16_t p3)
dsp_load_tch_param(&l1s.next_time,
SIG_ONLY_MODE, SDCCH_4, 0, 0, 0, tn);
- dsp_load_tx_task(DUL_DSP_TASK, burst_id, tsc);
+ dsp_load_tx_task(
+ dsp_task_iq_swap(DUL_DSP_TASK, arfcn, 1),
+ burst_id, tsc
+ );
l1s_tx_win_ctrl(arfcn | ARFCN_UPLINK, L1_TXWIN_NB, 0, 3);
diff --git a/src/target/firmware/rf/trf6151.c b/src/target/firmware/rf/trf6151.c
index 96210fc..0a91009 100644
--- a/src/target/firmware/rf/trf6151.c
+++ b/src/target/firmware/rf/trf6151.c
@@ -603,3 +603,17 @@ void trf6151_compute_gain(int16_t exp_inp, int16_t target_bb)
trf6151_set_gain(delta);
}
+int trf6151_iq_swapped(uint16_t band_arfcn, int tx)
+{
+ if (!tx)
+ return 0;
+
+ switch (gsm_arfcn2band(band_arfcn)) {
+ case GSM_BAND_850:
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}