diff options
author | Harald Welte <laforge@gnumonks.org> | 2010-02-21 09:46:51 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2010-03-01 23:48:43 +0100 |
commit | 1327bbd6fd844c3bf7d25410bbe1579afd8d818c (patch) | |
tree | aa6a4bb3084a31519e03eedfb6cad68d837c369f /src/target/firmware/rf | |
parent | 32da71ef5ccb01d1a6f91657661637ba2a451196 (diff) |
TRF6151: add Uplink support
Diffstat (limited to 'src/target/firmware/rf')
-rw-r--r-- | src/target/firmware/rf/trf6151.c | 68 |
1 files changed, 66 insertions, 2 deletions
diff --git a/src/target/firmware/rf/trf6151.c b/src/target/firmware/rf/trf6151.c index 6b9691f2..a155947c 100644 --- a/src/target/firmware/rf/trf6151.c +++ b/src/target/firmware/rf/trf6151.c @@ -171,6 +171,48 @@ static uint16_t trf6151_pll_rx(uint32_t freq_khz) return PLL_VAL(a, b); } +/* Compute TRF6151 PLL TX values for GSM900 and GSM1800 only! */ +static uint16_t trf6151_pll_tx(uint32_t freq_khz) +{ + uint32_t freq_100khz = freq_khz / SCALE_100KHZ; /* Scale from *1000 (k) to *100000 (0.1M) */ + uint32_t fb_100khz; /* frequency of B alone, without A (units of 100kHz) */ + uint32_t l, r, m; + uint32_t b10; /* B value expanded by a factor of 10 */ + uint32_t a, b; /* The PLL multipliers we want to compute */ + + /* L = 4 for low band, 2 for high band */ + if (freq_khz < 1000000) { + r = 35; + l = 4; + m = 52; + } else { + r = 70; + l = 2; + m = 26; + } + + /* To compute B, we assume A is zero */ + b = (freq_100khz * r * l * m) / (64 * 26 * 10 * (m + l)); + + if ((l == 4 && (b < 68 || b > 71)) || + (l == 2 && (b < 133 || b > 149))) + printf("Frequency %u kHz is out of spec\n", freq_khz); + + /* Compute PLL frequency assuming A == 0 */ + fb_100khz = (b * 64 * 26 * 10 * (m + l)) / (r * l * m); + + /* Compute how many 100kHz units A needs to add */ + a = freq_100khz - fb_100khz; + + a = a / 2; + + /* since all frequencies are expanded a factor of 10, we don't need to multiply A */ + printd("Freq %u kHz => A = %u, B = %u\n", freq_khz, a, b); + + /* return value in trf6151 register layout form */ + return PLL_VAL(a, b); +} + enum trf6151_pwr_unit { TRF1651_PACTLR_APC, TRF6151_PACTRL_APCEN, @@ -240,7 +282,11 @@ void trf6151_set_mode(enum trf6151_mode mode) pwr |= (PWR_SYNTHE_RX_ON | PWR_RX_MODE); break; case TRF6151_TX: +#if 0 pwr |= (PWR_SYNTHE_TX_ON | PWR_TX_MODE); +#else // Dieter: we should turn power control on (for TPU: check timing and order !) + pwr |= (PWR_SYNTHE_TX_ON | PWR_TX_MODE | PWR_PACTRL_APC | PWR_PACTRL_APCEN); // Dieter: TODO +#endif break; } trf6151_reg_write(REG_PWR, pwr); @@ -289,8 +335,13 @@ void trf6151_set_arfcn(uint16_t arfcn, int uplink) if (uplink == 0) trf6151_reg_write(REG_PLL, trf6151_pll_rx(freq_khz)); - else - printf("We don't support uplink tuning yet!\n"); + else { + if (rf_band != GSM900 && rf_band != GSM1800) { + printf("TX only supports GSM900/1800\n"); + return; + } + trf6151_reg_write(REG_PLL, trf6151_pll_tx(freq_khz)); + } rf_arfcn = arfcn; // TODO: arfcn is referenced at other places } @@ -356,6 +407,19 @@ void trf6151_test(uint16_t arfcn) tpu_wait_idle(); } +void trf6151_tx_test(uint16_t arfcn) +{ + /* Select ARFCN uplink */ + trf6151_set_arfcn(arfcn, 1); + + trf6151_set_mode(TRF6151_TX); + tpu_enq_wait(TRF6151_RX_PLL_DELAY); + + tpu_enq_sleep(); + tpu_enable(1); + tpu_wait_idle(); +} + #define TRF6151_REGWR_QBITS 8 /* 4 GSM qbits + 4 TPU instructions */ #define TRF6151_RX_TPU_INSTR 4 /* set_gain(1), set_arfcn(2), set_mode(1) */ |