B4R Question Calculation and Variable Type

mw71

Active Member
Licensed User
Longtime User
Hi

i am still "translate" this code:
https://www.qrp-labs.com/images/synth/demo4/oscillator.ino

Now i have check the output to I2C from the original Code and my Code.... it's diffrent at 2 position.

I check the Log to enclose the problem

f = fvco - (a * F_XTAL) 'F_XTAL ist ULong, Float the same
original: 9000000.00
my code: 9000034 (or 9000000, depend on Variable Type)

f = f * c
original: 9437166200000.00
my code: ovf (overflow??)

i think its depend on Variable Typ??

the Code i use:
B4X:
Sub SetFrequency (frequency_in As ULong, offset As UInt)
Dim frequency As ULong = (frequency_in * 1000)-offset
Log("Set QRG: ",frequency)
 
Dim c As Float = 1048574            ' "c" part of Feedback-Multiplier from XTAL to PLL
Dim fvco As Float                      ' VCO frequency (600-900 MHz) of PLL
Dim outdivider As ULong                ' Output divider in range [4,6,8-900], even numbers preferred
Dim R As Byte = 1                   ' Additional Output Divider in range [1,2,4,...128]
Dim a As Byte                       ' "a" part of Feedback-Multiplier from XTAL To PLL in range [15,90]
Dim b As Float                        ' "b" part of Feedback-Multiplier from XTAL To PLL
Dim f As Float                      ' floating variable, needed in calculation
Dim MS0_P1 As Float                    ' Si5351a Output Divider register MS0_P1, P2 And P3 are hardcoded below
Dim MSNA_P1 As Float                  ' Si5351a Feedback Multisynth register MSNA_P1
Dim MSNA_P2 As Float                  ' Si5351a Feedback Multisynth register MSNA_P2
Dim MSNA_P3 As Float                  ' Si5351a Feedback Multisynth register MSNA_P3

'this (orginial def also not work)
'Dim c As ULong = 1048574            ' "c" part of Feedback-Multiplier from XTAL to PLL
'Dim fvco As ULong                      ' VCO frequency (600-900 MHz) of PLL
'Dim outdivider As ULong                ' Output divider in range [4,6,8-900], even numbers preferred
'Dim R As Byte = 1                   ' Additional Output Divider in range [1,2,4,...128]
'Dim a As Byte                       ' "a" part of Feedback-Multiplier from XTAL To PLL in range [15,90]
'Dim b As ULong                        ' "b" part of Feedback-Multiplier from XTAL To PLL
'Dim f As Float                      ' floating variable, needed in calculation
'Dim MS0_P1 As ULong                    ' Si5351a Output Divider register MS0_P1, P2 And P3 are hardcoded below
'Dim MSNA_P1 As ULong                  ' Si5351a Feedback Multisynth register MSNA_P1
'Dim MSNA_P2 As ULong                  ' Si5351a Feedback Multisynth register MSNA_P2
'Dim MSNA_P3 As ULong                  ' Si5351a Feedback Multisynth register MSNA_P3

outdivider = 900000000 / frequency  ' With 900 MHz beeing the maximum internal PLL-Frequency

Do While outdivider > 900            ' If output divider out of range (>900) use additional Output divider
    R = R * 2
    outdivider = outdivider / 2
Loop
If outdivider Mod 2<>0 Then outdivider=outdivider-1

fvco = outdivider * R * frequency    ' Calculate the PLL-Frequency (given the even divider)


Select Case R                          ' Convert the Output Divider To the Bit-setting required in register 44
    Case 1: R = 0              ' Bits [6:4] = 000
    Case 2: R = 16             ' Bits [6:4] = 001
    Case 4: R = 32             ' Bits [6:4] = 010
    Case 8: R = 48             ' Bits [6:4] = 011
    Case 16: R = 64            ' Bits [6:4] = 100
    Case 32: R = 80            ' Bits [6:4] = 101
    Case 64: R = 96            ' Bits [6:4] = 110
    Case 128: R = 112          ' Bits [6:4] = 111
End Select

    a = fvco / F_XTAL                   ' Multiplier To get from Quartz-Oscillator Freq. to PLL-Freq.
    f = fvco - (a * F_XTAL)               ' Multiplier = a+b/c
    f = f * c                           ' this is just "int" And "float" mathematics
    f = f / F_XTAL
    b = f
 
    MS0_P1 = 128 * outdivider - 512     ' Calculation of Output Divider registers MS0_P1 To MS0_P3
 
    f = 128 * b / c                     ' Calculation of Feedback Multisynth registers MSNA_P1 To MSNA_P3
    MSNA_P1 = 128 * a + f - 512
    MSNA_P2 = f
    MSNA_P2 = 128 * b - MSNA_P2 * c
    MSNA_P3 = c
    
    
    Si5351a_Write_Reg (16, 128)                                          ' Disable output during the following register settings
    Si5351a_Write_Reg (26, Bit.ShiftRight(Bit.And(MSNA_P3,65280),8))      ' Bits [15:8] of MSNA_P3 in register 26
    Si5351a_Write_Reg (27, Bit.And(MSNA_P3,255))                        ' Bits [7:0]  of MSNA_P3 in register 27
    Si5351a_Write_Reg (28, Bit.ShiftRight(Bit.And(MSNA_P1,196608),16))     ' Bits [17:16] of MSNA_P1 in bits [1:0] of register 28
    Si5351a_Write_Reg (29, Bit.ShiftRight(Bit.And(MSNA_P1,65280),8))      ' Bits [15:8]  of MSNA_P1 in register 29
    Si5351a_Write_Reg (30, Bit.And(MSNA_P1,255))                          ' Bits [7:0]  of MSNA_P1 in register 30
    Si5351a_Write_Reg (31, Bit.Or(Bit.ShiftRight(Bit.And(MSNA_P3,983040),12),Bit.ShiftRight(Bit.And(MSNA_P2,983040),16))) ' Parts of MSNA_P3 und MSNA_P1
    Si5351a_Write_Reg (32, Bit.ShiftRight(Bit.And(MSNA_P2,65280),8))     ' Bits [15:8]  of MSNA_P2 in register 32
    Si5351a_Write_Reg (33, Bit.And(MSNA_P2,255))                          ' Bits [7:0]  of MSNA_P2 in register 33
    Si5351a_Write_Reg (42, 0)                                            ' Bits [15:8] of MS0_P3 (always 0) in register 42
    Si5351a_Write_Reg (43, 1)                                            ' Bits [7:0]  of MS0_P3 (always 1) in register 43
    Si5351a_Write_Reg (44, Bit.Or(Bit.ShiftRight(Bit.And(MS0_P1,196608),16),R))  ' Bits [17:16] of MS0_P1 in bits [1:0] And R in [7:4]
    Si5351a_Write_Reg (45, Bit.ShiftRight(Bit.And(MS0_P1, 65280),8))    ' Bits [15:8]  of MS0_P1 in register 45
    Si5351a_Write_Reg (46, Bit.And(MS0_P1, 255))                        ' Bits [7:0]  of MS0_P1 in register 46
    Si5351a_Write_Reg (47, 0)                                            ' Bits [19:16] of MS0_P2 And MS0_P3 are always 0
    Si5351a_Write_Reg (48, 0)                                            ' Bits [15:8]  of MS0_P2 are always 0
    Si5351a_Write_Reg (49, 0)                                            ' Bits [7:0]   of MS0_P2 are always 0
    If outdivider = 4 Then
        Si5351a_Write_Reg (44, Bit.Or(12,R))              ' Special settings For R = 4 (see datasheet)
        Si5351a_Write_Reg (45, 0)                          ' Bits [15:8]  of MS0_P1 must be 0
        Si5351a_Write_Reg (46, 0)                          ' Bits [7:0]  of MS0_P1 must be 0
    End If
    Si5351a_Write_Reg (177, 32)                          ' This resets PLL A
End Sub

Does somebody has any idea?
 
Last edited:

mw71

Active Member
Licensed User
Longtime User
hi

it's the complete Project, but you can it run without LCD, Encoder....., only the blank Board is need.
After Start the SetFrequency Sub in the SI5351 Code Modul is calling. There is the Problem (and code above)
 

Attachments

  • Test_SI5351.zip
    9.8 KB · Views: 204
Upvote 0

thetahsk

Active Member
Licensed User
Longtime User
hi

it's the complete Project, but you can it run without LCD, Encoder....., only the blank Board is need.
After Start the SetFrequency Sub in the SI5351 Code Modul is calling. There is the Problem (and code above)

Check your global Dim F_XTAL As Float variable. It produces a division by zero in SetFrequency(..,..).

B4X:
...
    a = fvco / F_XTAL                   ' Multiplier To get from Quartz-Oscillator Freq. to PLL-Freq.
    Log("5,:"&a)
    f = fvco - (a * F_XTAL)               ' Multiplier = a+b/c
    Log("6,:"&f)
    f = f * c                           ' this is just "int" And "float" mathematics
     Log("7,:"&f)
    f = f / F_XTAL
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
Check your global Dim F_XTAL As Float variable. It produces a division by zero in SetFrequency(..,..).

F_XTAL is original ULong, change to Float was s test. Boot not o.k. (different results, but both wrong)

Test the Calculation with Inline C o.k., but i cant call the other "Sub" in Inline C (i search the way......)
 
Upvote 0

mw71

Active Member
Licensed User
Longtime User
thanks for the Tip, but i would like call a "Sub" (void?) in Inline C from Inline C.
I have found the Solution, i must declare the "Sub" before. it works.
 
Upvote 0
Top