firmware: fractional sample rates
This commit is contained in:
@ -39,6 +39,69 @@ void delay(uint32_t duration)
|
||||
__asm__("nop");
|
||||
}
|
||||
|
||||
bool set_fracrate(const float freq) {
|
||||
|
||||
uint32_t MSx_P1,MSx_P2,MSx_P3;
|
||||
uint32_t b,c;
|
||||
float div = (800/freq);
|
||||
uint32_t a = (uint32_t)div;
|
||||
float x = div-a;
|
||||
|
||||
if(a != div){
|
||||
uint32_t j=0,k=1,l=1,m=1;
|
||||
while (k <= 0xFFFF && m <= 0xFFFF){
|
||||
float n = (float)(j+l)/(k+m);
|
||||
if( x == n){
|
||||
if(k + m <= 0xFFFF){
|
||||
b=j+l; c=k+m;
|
||||
break;
|
||||
} else if(m > k){
|
||||
b=l; c=m;
|
||||
break;
|
||||
} else {
|
||||
b=j; c=k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(x > n){
|
||||
j+=l; k+=m;
|
||||
}
|
||||
else{
|
||||
l+=j; m+=k;
|
||||
}
|
||||
}
|
||||
if (k > 0xFFFF){
|
||||
b=l; c=m;
|
||||
}
|
||||
else{
|
||||
b=j; c=k;
|
||||
}
|
||||
} else {
|
||||
b=0; c=1;
|
||||
}
|
||||
|
||||
MSx_P1 = 128*a + (128 * b/c) - 512;
|
||||
MSx_P2 = (128*b)%c;
|
||||
MSx_P3 = c;
|
||||
|
||||
|
||||
/* MS0/CLK0 is the source for the MAX5864/CPLD (CODEC_CLK). */
|
||||
si5351c_configure_multisynth(0, MSx_P1, MSx_P2, MSx_P3, 1);
|
||||
|
||||
/* MS0/CLK1 is the source for the CPLD (CODEC_X2_CLK). */
|
||||
si5351c_configure_multisynth(1, 0, 0, 0, 0);//p1 doesn't matter
|
||||
|
||||
/* MS0/CLK2 is the source for SGPIO (CODEC_X2_CLK) */
|
||||
si5351c_configure_multisynth(2, 0, 0, 0, 0);//p1 doesn't matter
|
||||
|
||||
/* MS0/CLK3 is the source for the external clock output. */
|
||||
//si5351c_configure_multisynth(3, p1, 0, 1, 0); // no clk out
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool sample_rate_set(const uint32_t sample_rate_hz) {
|
||||
#ifdef JELLYBEAN
|
||||
/* Due to design issues, Jellybean/Lemondrop frequency plan is limited.
|
||||
|
@ -259,6 +259,7 @@ void pin_setup(void);
|
||||
|
||||
void enable_1v8_power(void);
|
||||
|
||||
bool set_fracrate(const float sampling_rate_mhz);
|
||||
bool sample_rate_set(const uint32_t sampling_rate_hz);
|
||||
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_hz);
|
||||
|
||||
|
@ -230,20 +230,20 @@ void si5351c_configure_clock_control()
|
||||
void si5351c_configure_clock_control()
|
||||
{
|
||||
uint8_t data[] = {16
|
||||
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
|
||||
,SI5351C_CLK_FRAC_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
|
||||
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
|
||||
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_0_4) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
|
||||
,SI5351C_CLK_POWERDOWN /*not connected, clock out*/
|
||||
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
|
||||
,SI5351C_CLK_INT_MODE | SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
|
||||
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /*not connected, but: plla int mode*/
|
||||
,SI5351C_CLK_POWERDOWN/* pllb int mode*/| SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_A) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
|
||||
,SI5351C_CLK_POWERDOWN | SI5351C_CLK_INT_MODE /* pllb int mode*/| SI5351C_CLK_PLL_SRC(SI5351C_CLK_PLL_SRC_B) | SI5351C_CLK_SRC(SI5351C_CLK_SRC_MULTISYNTH_SELF) | SI5351C_CLK_IDRV(SI5351C_CLK_IDRV_8MA)
|
||||
};
|
||||
si5351c_write(data, sizeof(data));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Enable CLK outputs 0, 1, 2, 4, 5, 7 only. */
|
||||
/* Enable CLK outputs 0, 1, 2, 4, 5, ~7 only. */
|
||||
void si5351c_enable_clock_outputs()
|
||||
{
|
||||
uint8_t data[] = { 3, 0xC8 };
|
||||
|
@ -35,6 +35,7 @@ extern "C"
|
||||
|
||||
#define SI5351C_CLK_POWERDOWN (1<<7)
|
||||
#define SI5351C_CLK_INT_MODE (1<<6)
|
||||
#define SI5351C_CLK_FRAC_MODE (0<<6)
|
||||
|
||||
#define SI5351C_CLK_PLL_SRC(x) (x<<5)
|
||||
#define SI5351C_CLK_PLL_SRC_A 0
|
||||
|
@ -67,6 +67,12 @@ typedef struct {
|
||||
|
||||
set_freq_params_t set_freq_params;
|
||||
|
||||
typedef struct {
|
||||
float freq_mhz;
|
||||
} set_sample_r_params_t;
|
||||
|
||||
set_sample_r_params_t set_sample_r_params;
|
||||
|
||||
uint8_t switchctrl = 0;
|
||||
|
||||
void update_switches(void)
|
||||
@ -696,6 +702,28 @@ usb_request_status_t usb_vendor_request_set_freq(
|
||||
}
|
||||
}
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_fracrate(
|
||||
usb_endpoint_t* const endpoint,
|
||||
const usb_transfer_stage_t stage)
|
||||
{
|
||||
if (stage == USB_TRANSFER_STAGE_SETUP)
|
||||
{
|
||||
usb_endpoint_schedule(endpoint->out, &set_sample_r_params, sizeof(set_sample_r_params_t));
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
} else if (stage == USB_TRANSFER_STAGE_DATA)
|
||||
{
|
||||
if( set_fracrate(set_sample_r_params.freq_mhz*2) )
|
||||
{
|
||||
usb_endpoint_schedule_ack(endpoint->in);
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
return USB_REQUEST_STATUS_STALL;
|
||||
} else
|
||||
{
|
||||
return USB_REQUEST_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
usb_request_status_t usb_vendor_request_set_amp_enable(
|
||||
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
||||
{
|
||||
@ -821,7 +849,8 @@ static const usb_request_handler_fn vendor_request_handler[] = {
|
||||
usb_vendor_request_read_partid_serialno,
|
||||
usb_vendor_request_set_lna_gain,
|
||||
usb_vendor_request_set_vga_gain,
|
||||
usb_vendor_request_set_txvga_gain
|
||||
usb_vendor_request_set_txvga_gain,
|
||||
usb_vendor_request_set_fracrate
|
||||
};
|
||||
|
||||
static const uint32_t vendor_request_handler_count =
|
||||
|
Reference in New Issue
Block a user