firmware: fractional sample rates

This commit is contained in:
Hoernchen
2013-06-06 14:10:20 +02:00
parent cd7da974d5
commit 1925649a01
5 changed files with 98 additions and 4 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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 };

View File

@ -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

View File

@ -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 =