diff --git a/firmware/common/hackrf_core.c b/firmware/common/hackrf_core.c index d1be02e7..7246d222 100644 --- a/firmware/common/hackrf_core.c +++ b/firmware/common/hackrf_core.c @@ -49,6 +49,9 @@ bool set_fracrate(const float freq) { if(a != div){ uint32_t j=0,k=1,l=1,m=1; + + si5351c_set_int_mode(0, 0); + while (k <= 0xFFFF && m <= 0xFFFF){ float n = (float)(j+l)/(k+m); if( x == n){ @@ -77,6 +80,10 @@ bool set_fracrate(const float freq) { b=j; c=k; } } else { + if(a & 0x1) // odd integer, needs frac mode + si5351c_set_int_mode(0, 0); + else + si5351c_set_int_mode(0, 1); b=0; c=1; } diff --git a/firmware/common/si5351c.c b/firmware/common/si5351c.c index 6cc0d253..e661fbc0 100644 --- a/firmware/common/si5351c.c +++ b/firmware/common/si5351c.c @@ -249,3 +249,21 @@ void si5351c_configure_clock_control() uint8_t data[] = { 3, 0xC8 }; si5351c_write(data, sizeof(data)); } + + + void si5351c_set_int_mode(const uint_fast8_t ms_number, const uint_fast8_t on){ + uint8_t data[] = {16, 0}; + + if(ms_number < 8){ + data[0] = 16 + ms_number; + data[1] = si5351c_read_single(data[0]); + + if(on) + data[1] |= SI5351C_CLK_INT_MODE; + else + data[1] &= ~(SI5351C_CLK_INT_MODE); + + si5351c_write(data, 2); + } + + } diff --git a/firmware/common/si5351c.h b/firmware/common/si5351c.h index 12f1dc3a..a2867438 100644 --- a/firmware/common/si5351c.h +++ b/firmware/common/si5351c.h @@ -67,6 +67,7 @@ void si5351c_configure_multisynth(const uint_fast8_t ms_number, const uint_fast8_t r_div); void si5351c_configure_clock_control(); void si5351c_enable_clock_outputs(); +void si5351c_set_int_mode(const uint_fast8_t ms_number, const uint_fast8_t on); void si5351c_write_single(uint8_t reg, uint8_t val); uint8_t si5351c_read_single(uint8_t reg); diff --git a/host/hackrf-tools/src/hackrf_si5351c.c b/host/hackrf-tools/src/hackrf_si5351c.c index f9e86910..0a447d45 100644 --- a/host/hackrf-tools/src/hackrf_si5351c.c +++ b/host/hackrf-tools/src/hackrf_si5351c.c @@ -109,53 +109,60 @@ int dump_multisynth_config(hackrf_device* device, const uint_fast8_t ms_number) uint32_t p1,p2,p3,r_div; uint_fast8_t div_lut[] = {1,2,4,8,16,32,64,128}; - printf("MS%d:", ms_number); - if(ms_number <6){ - reg_base = 42 + (ms_number * 8); - for(i=0; i<8; i++) { - uint_fast8_t reg_number = reg_base + i; - int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); - if( result != HACKRF_SUCCESS ) { - return result; - } - } + printf("MS%d:", ms_number); + if(ms_number <6){ + reg_base = 42 + (ms_number * 8); + for(i=0; i<8; i++) { + uint_fast8_t reg_number = reg_base + i; + int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); + if( result != HACKRF_SUCCESS ) { + return result; + } + } - p1 = - (parameters[2] & 0x03 << 16) - | (parameters[3] << 8) - | parameters[4] - ; - p2 = - (parameters[5] & 0x0F << 16) - | (parameters[6] << 8) - | parameters[7] - ; - p3 = - (parameters[5] & 0xF0 << 12) - | (parameters[0] << 8) - | parameters[1] - ; - r_div = - (parameters[2] >> 4) & 0x7 - ; + p1 = + (parameters[2] & 0x03 << 16) + | (parameters[3] << 8) + | parameters[4] + ; + p2 = + (parameters[5] & 0x0F << 16) + | (parameters[6] << 8) + | parameters[7] + ; + p3 = + (parameters[5] & 0xF0 << 12) + | (parameters[0] << 8) + | parameters[1] + ; + r_div = + (parameters[2] >> 4) & 0x7 + ; - printf("\tp1 = %u\n", p1); - printf("\tp2 = %u\n", p2); - printf("\tp3 = %u\n", p3); - } else { - // MS6 and 7 are integer only - reg_base = 90; - for(i=0; i<3; i++) { - uint_fast8_t reg_number = reg_base + i; - int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); - if( result != HACKRF_SUCCESS ) { - return result; - } - } + printf("\tp1 = %u\n", p1); + printf("\tp2 = %u\n", p2); + printf("\tp3 = %u\n", p3); + if(p3) + printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", (800 / (float)((p1*p3 + p2 + 512*p3)/(128*p3))) / div_lut[r_div] ); + } else { + // MS6 and 7 are integer only + unsigned int parms; + reg_base = 90; - r_div = (ms_number == 6) ? parameters[2] & 0x7 : parameters[2] & 0x70 >> 4 ; - printf("\tp1_int = %u\n", (ms_number == 6) ? parameters[0] : parameters[1]); - } + for(i=0; i<3; i++) { + uint_fast8_t reg_number = reg_base + i; + int result = hackrf_si5351c_read(device, reg_number, ¶meters[i]); + if( result != HACKRF_SUCCESS ) { + return result; + } + } + + r_div = (ms_number == 6) ? parameters[2] & 0x7 : parameters[2] & 0x70 >> 4 ; + parms = (ms_number == 6) ? parameters[0] : parameters[1]; + printf("\tp1_int = %u\n", parms); + if(parms) + printf("\tOutput (800Mhz PLL): %#.10f Mhz\n", (800.0f / parms) / div_lut[r_div] ); + } printf("\toutput divider = %u\n", div_lut[r_div]); return HACKRF_SUCCESS; @@ -236,6 +243,6 @@ int main(int argc, char** argv) { } hackrf_exit(); - - return 0; + + return 0; } diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index b09e5ac0..49a89fc9 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -770,8 +770,6 @@ typedef struct { int ADDCALL hackrf_set_fracrate(hackrf_device* device, const float freq_mhz) { - uint32_t l_freq_mhz; - uint32_t l_freq_hz; set_fracrate_params_t set_fracrate_params; uint8_t length; int result;