firmware: fractional sample rates
This commit is contained in:
@ -39,6 +39,69 @@ void delay(uint32_t duration)
|
|||||||
__asm__("nop");
|
__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) {
|
bool sample_rate_set(const uint32_t sample_rate_hz) {
|
||||||
#ifdef JELLYBEAN
|
#ifdef JELLYBEAN
|
||||||
/* Due to design issues, Jellybean/Lemondrop frequency plan is limited.
|
/* Due to design issues, Jellybean/Lemondrop frequency plan is limited.
|
||||||
|
@ -259,6 +259,7 @@ void pin_setup(void);
|
|||||||
|
|
||||||
void enable_1v8_power(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 sample_rate_set(const uint32_t sampling_rate_hz);
|
||||||
bool baseband_filter_bandwidth_set(const uint32_t bandwidth_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()
|
void si5351c_configure_clock_control()
|
||||||
{
|
{
|
||||||
uint8_t data[] = {16
|
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_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_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_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 | 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));
|
si5351c_write(data, sizeof(data));
|
||||||
}
|
}
|
||||||
#endif
|
#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()
|
void si5351c_enable_clock_outputs()
|
||||||
{
|
{
|
||||||
uint8_t data[] = { 3, 0xC8 };
|
uint8_t data[] = { 3, 0xC8 };
|
||||||
|
@ -35,6 +35,7 @@ extern "C"
|
|||||||
|
|
||||||
#define SI5351C_CLK_POWERDOWN (1<<7)
|
#define SI5351C_CLK_POWERDOWN (1<<7)
|
||||||
#define SI5351C_CLK_INT_MODE (1<<6)
|
#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(x) (x<<5)
|
||||||
#define SI5351C_CLK_PLL_SRC_A 0
|
#define SI5351C_CLK_PLL_SRC_A 0
|
||||||
|
@ -67,6 +67,12 @@ typedef struct {
|
|||||||
|
|
||||||
set_freq_params_t set_freq_params;
|
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;
|
uint8_t switchctrl = 0;
|
||||||
|
|
||||||
void update_switches(void)
|
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_request_status_t usb_vendor_request_set_amp_enable(
|
||||||
usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage)
|
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_read_partid_serialno,
|
||||||
usb_vendor_request_set_lna_gain,
|
usb_vendor_request_set_lna_gain,
|
||||||
usb_vendor_request_set_vga_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 =
|
static const uint32_t vendor_request_handler_count =
|
||||||
|
Reference in New Issue
Block a user