Return value of function read_io()

Hello!

I try to build GNURadio with OpenBTS on a Ubuntu Linux system. I have
the current revision of the repository running (10393).
GNURadio was built successfully and works, but OpenBTS didn’t work,
because RX failed to tune.

Following errors occur:
TRXManager.cpp:
WARNING – RXTUNE failed with status 1
POWERON – failed with status 1
Transceiver.cpp:
RX failed to tune

I ask my question in the GNURadio discussion list, because the problem
is related to the USRP and his registers.

I have the source code (see below) and the function “rx_setFreq” which
is called with the parameter freq = 1716400000,000000 (is calculated
with 1724,4MHz: 1724400000.000000 -24000000 = wFreq-2LO_OFFSET)
And then the function “compute_regs” is called. This function seems to
be similar to usrp2/firmware/lib/db_rfx.c - “bool rfx_set_freq”.

My problem is this line in the OpenBTS source code:
if (m_uRx->read_io(1) & PLL_LOCK_DETECT) return true;

m_uRx->read_io(1) = 0xff3b = 1111 1111 0011 1011
PLL_LOCK_DETECT = 0x4 = 0000 0000 0000 0100
so the if condition is false it doesn’t return true, but it should
return true.

So I test several frequencies for looking after the value of m_uRx-

read_io(1):

-> GSM 1800 frequency -> m_uRx->read_io(1) = 0xff3b -> does not
tune, because Bit 2 is 0
-> GSM 850 and 900 frequencies -> m_uRx->read_io(1) = 0xff3f -> does
tune, because Bit 2 is 1 (but I don’t have RFX900 daughterboards)

My questions: What does the function read_io(1) return? The values
written to the fpga with function “_write_spi” N, R and control aren’t
the values returned by read_io()?!

In my example with ARFCN 583 (1724,4MHz & 1819,4MHz) The values of R,
N, control are:
Function rx_setFreq, (R & ~0x3) = 0x340040
Function rx_setFreq, (R & ~0x3) | 1 = 0x340041
Function rx_setFreq, (control & ~0x3) = 0x4fc924
Function rx_setFreq, (control & ~0x3) | 0 = 0x4fc924
Function rx_setFreq, (N & ~0x3) = 0x403528
Function rx_setFreq, (N & ~0x3) | 2 = 0x40352a

How does it calculate and return 0xff3b? And why does it only for
GSM850/GSM900 return 0xff3f and not for GSM1800 (0xff3b)?

Thanks & Regards
-Fabian-


Source code of openbts/Transceiver/USRPDevice.cpp:

bool USRPDevice::rx_setFreq(double freq, double *actual_freq)
{
unsigned R, control, N;
printf(“Function rx_setFreq, freq=%lf\n”, freq);
if (!compute_regs(freq, &R, &control, &N, actual_freq)) return false;
printf(“Function rx_setFreq, R=%x\n”, R);
printf(“Function rx_setFreq, control=%x\n”, control);
printf(“Function rx_setFreq, N=%x\n”, N);
if (R==0) return false;
// static const unsigned SPI_FMT_MSB = (0 << 7);
// static const unsigned SPI_ENABLE_RX_B = 0x80;
// static const unsigned SPI_FMT_HDR_0 = (0 << 5);

printf(“Function rx_setFreq, SPI_ENABLE_RX_B=%x\n”, SPI_ENABLE_RX_B);
printf(“Function rx_setFreq, SPI_FMT_MSB | SPI_FMT_HDR_0=%x\n”,
SPI_FMT_MSB | SPI_FMT_HDR_0);
printf(“Function rx_setFreq, (R & ~0x3)=%x\n”, (R & ~0x3));
printf(“Function rx_setFreq, (R & ~0x3) | 1=%x\n”, (R & ~0x3) | 1);

m_uRx->_write_spi(0,SPI_ENABLE_RX_B,SPI_FMT_MSB | SPI_FMT_HDR_0,
write_it((R & ~0x3) | 1));
printf(“Function rx_setFreq, (control & ~0x3)=%x\n”, (control &
~0x3));
printf(“Function rx_setFreq, (control & ~0x3) | 0=%x\n”, (control &
~0x3) | 0);
m_uRx->_write_spi(0,SPI_ENABLE_RX_B,SPI_FMT_MSB | SPI_FMT_HDR_0,
write_it((control & ~0x3) | 0));
usleep(10000);
printf(“Function rx_setFreq, (N & ~0x3)=%x\n”, (N & ~0x3));
printf(“Function rx_setFreq, (N & ~0x3) | 2=%x\n”, (N & ~0x3) | 2);
m_uRx->_write_spi(0,SPI_ENABLE_RX_B,SPI_FMT_MSB | SPI_FMT_HDR_0,
write_it((N & ~0x3) | 2));
printf(“Function rx_setFreq, m_uRx->read_io(1)=%x\n”, m_uRx-

read_io(1));
printf(“Function rx_setFreq, PLL_LOCK_DETECT=%x\n”, PLL_LOCK_DETECT);
if (m_uRx->read_io(1) & PLL_LOCK_DETECT) return true;
if (m_uRx->read_io(1) & PLL_LOCK_DETECT) return true;

return false;
}


Source code of openbts/Transceiver/USRPDevice.cpp:

const float USRPDevice::LO_OFFSET = 4.0e6;

bool USRPDevice::compute_regs(double freq,
unsigned *R,
unsigned *control,
unsigned *N,
double *actual_freq)
{

float phdet_freq = 64.0e6/R_DIV;
int desired_n = (int) round(freq*freq_mult/phdet_freq);
actual_freq = desired_n * phdet_freq/freq_mult;
float B = floor(desired_n/16);
float A = desired_n - 16
B;
unsigned B_DIV = int(B);
unsigned A_DIV = int(A);

printf(“Function compute_regs, freq=%lf\n”, freq);
printf(“Function compute_regs, freq_mult=%i\n”, freq_mult);
printf(“Function compute_regs, R_DIV=%i\n”, R_DIV);
printf(“Function compute_regs, phdet_freq=%lf\n”, phdet_freq);
printf(“Function compute_regs, desired_n=%i\n”, desired_n);
printf(“Function compute_regs, actual_freq=%lf\n”, actual_freq);
printf(“Function compute_regs, B=%lf\n”, B);
printf(“Function compute_regs, A=%lf\n”, A);
printf(“Function compute_regs, B_DIV=%i\n”, B_DIV);
printf(“Function compute_regs, A_DIV=%i\n”, A_DIV);

if (B < A) return false;
*R = (R_RSV<<22) |
(BSC << 20) |
(TEST << 19) |
(LDP << 18) |
(ABP << 16) |
(R_DIV << 2);
*control = (P<<22) |
(PD<<20) |
(CP2 << 17) |
(CP1 << 14) |
(PL << 12) |
(MTLD << 11) |
(CPG << 10) |
(CP3S << 9) |
(PDP << 8) |
(MUXOUT << 5) |
(CR << 4) |
(PC << 2);
*N = (DIVSEL<<23) |
(DIV2<<22) |
(CPGAIN<<21) |
(B_DIV<<8) |
(N_RSV<<7) |
(A_DIV<<2);
return true;
}

Hello!

I can update my last entry a little bit: I tested the last 4 hours
this “compute_regs” function.

The values written to the FPGA are:
(R & ~0x3) | 1=340041
(control & ~0x3) | 0=4fc924
These two values are constant, so the return value of "m_uRx-

read_io(1)" should not influence the second Bit directly.
It must be the value of
(N & ~0x3) | 2
which decided if the USRP will tune or not, which calculation depends
on the desired frequency.

For example:
Setting
(N & ~0x3) | 2 = 0x401b32
-> m_uRx->read_io(1) return 0xff3f -> 2. Bit is 1 which is right

Setting
(N & ~0x3) | 2 = 0x403722
-> m_uRx->read_io(1) return 0xff3b -> 2. Bit is 0 which is wrong

-> So I think the error must be in the OpenBTS function “compute_regs”
calculating N.
Unfortunalety, I have to know how the read_io(1) works to solve the
problem.
Why does is return 0xff3b if N = 0x403722 and 0xff3f if N = 0x401b32?

Does anyone know that?

Thanks & Regards
-Fabian-