Forum: GNU Radio return value of function read_io()

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Feaa5f7ffb89464efdf3fdb028ad5c63?d=identicon&s=25 Fabian Uehlin (Guest)
on 2009-02-05 13:18
(Received via mailing list)
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 -2*4000000 = wFreq-2*LO_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;
}
Feaa5f7ffb89464efdf3fdb028ad5c63?d=identicon&s=25 Fabian Uehlin (Guest)
on 2009-02-05 22:01
(Received via mailing list)
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-
This topic is locked and can not be replied to.