Compare commits

...

5 Commits

1 changed files with 31 additions and 29 deletions

View File

@ -26,7 +26,7 @@ using namespace std::literals::chrono_literals;
void fft_mag(std::complex<float>* in, float* out, size_t len);
static const size_t block_len = 16384;
static const size_t frame_len = 16384;
static const int wf_width = 1000;
static const int wf_height = 1200;
@ -52,13 +52,13 @@ static void tec_thread()
else
return 1;
});
std::this_thread::sleep_for(100ms);
std::this_thread::sleep_for(15ms);
}
}
static std::atomic<bool> poh_accept_input;
static std::binary_semaphore poh_input_ready{0};
static std::complex<float> poh_input_block[block_len];
static std::complex<float> poh_input_frame[frame_len];
static std::mutex wf_poh_mutex;
static unsigned int wf_poh[wf_width*wf_height];
@ -69,17 +69,18 @@ static std::atomic<float> tec_p;
static void poh_thread()
{
std::vector<float> block_mag(block_len);
std::vector<float> frame_mag(frame_len);
poh_accept_input = true; // accept first frame
while(!shutdown_threads) {
poh_accept_input = true;
poh_input_ready.acquire();
fft_mag(poh_input_block, block_mag.data(), block_len);
fft_mag(poh_input_frame, frame_mag.data(), frame_len);
poh_accept_input = true; // poh_input_frame not used again until next iteration
// stabilize laser
float freq_peak_local;
freq_peak_local = 40.0f*float(distance(block_mag.begin(), max_element(block_mag.begin(), block_mag.end())))/float(block_len);
freq_peak_local = 40.0f*float(distance(frame_mag.begin(), max_element(frame_mag.begin(), frame_mag.end())))/float(frame_len);
freq_peak = freq_peak_local;
float freq_error = freq_peak_local - freq_setpoint;
tec_current = std::max(tec_bias+tec_p*freq_error, 0.0f);
@ -89,8 +90,8 @@ static void poh_thread()
std::lock_guard<std::mutex> guard(wf_poh_mutex);
std::memmove(&wf_poh[wf_width], &wf_poh[0], sizeof(int)*wf_width*(wf_height - 1));
for(int i=0;i<wf_width;i++) {
int j = i*block_len/wf_width;
wf_poh[i] = 0xff000000 | 0x010101*std::min(int(block_mag[j]/900.0f), 255);
int j = i*frame_len/wf_width;
wf_poh[i] = 0xff000000 | 0x010101*std::min(int(frame_mag[j]/900.0f), 255);
}
wf_poh[int(freq_setpoint*wf_width)/40] = 0xff0000ff;
}
@ -99,24 +100,25 @@ static void poh_thread()
static std::atomic<bool> ls_accept_input;
static std::binary_semaphore ls_input_ready{0};
static std::complex<float> ls_input_block[block_len];
static std::complex<float> ls_input_frame[frame_len];
static std::mutex wf_ls_mutex;
static unsigned int wf_ls[wf_width*wf_height];
static void ls_thread()
{
std::vector<float> block_mag(block_len);
std::vector<float> frame_mag(frame_len);
ls_accept_input = true;
while(!shutdown_threads) {
ls_accept_input = true;
ls_input_ready.acquire();
fft_mag(ls_input_block, block_mag.data(), block_len);
fft_mag(ls_input_frame, frame_mag.data(), frame_len);
ls_accept_input = true;
{
std::lock_guard<std::mutex> guard(wf_ls_mutex);
std::memmove(&wf_ls[wf_width], &wf_ls[0], sizeof(int)*wf_width*(wf_height - 1));
for(int i=0;i<wf_width;i++) {
int j = i*block_len/wf_width;
wf_ls[i] = 0xff000000 | 0x010101*std::min(int(block_mag[j]/900.0f), 255);
int j = i*frame_len/wf_width;
wf_ls[i] = 0xff000000 | 0x010101*std::min(int(frame_mag[j]/900.0f), 255);
}
}
}
@ -134,9 +136,9 @@ static void* brf_dispatch(struct bladerf* dev, struct bladerf_stream* stream,
{
if(poh_accept_input && ls_accept_input) {
std::complex<int16_t>* samples = (std::complex<int16_t>*)samples_v;
for(size_t i=0;i<block_len;i++) {
poh_input_block[i] = samples[2*i];
ls_input_block[i] = samples[2*i+1];
for(size_t i=0;i<frame_len;i++) {
poh_input_frame[i] = samples[2*i];
ls_input_frame[i] = samples[2*i+1];
}
poh_accept_input = false;
poh_input_ready.release();
@ -196,7 +198,7 @@ static void brf_thread()
}
}
if((status = bladerf_init_stream(&brf_stream, brf_dev, brf_dispatch, &brf_buffers,
16, BLADERF_FORMAT_SC16_Q11, 2*block_len, 8, NULL)) != 0) {
16, BLADERF_FORMAT_SC16_Q11, 2*frame_len, 8, NULL)) != 0) {
std::cerr << "failed to init bladeRF stream: " << bladerf_strerror(status) << std::endl;
return;
}
@ -239,7 +241,7 @@ int main(int argc, char* argv[])
std::atexit(glfwTerminate);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
static GLFWwindow* window = glfwCreateWindow(1500, 2200, "fastsa", nullptr, nullptr);
static GLFWwindow* window = glfwCreateWindow(2600, 1350, "fastsa", nullptr, nullptr);
if(window == nullptr) {
std::cerr << "failed to create GLFW window" << std::endl;
return 1;
@ -307,9 +309,9 @@ int main(int argc, char* argv[])
bool exit = false;
bool update_wf = true;
float freq_setpoint_local = 0.0f;
float tec_bias_local = 0.02f;
float tec_p_local = 0.001f;
float freq_setpoint_local = 25.8f;
float tec_bias_local = 0.105f;
float tec_p_local = -0.022f;
while(!exit && !glfwWindowShouldClose(window)) {
glfwPollEvents();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
@ -341,20 +343,20 @@ int main(int argc, char* argv[])
ImGui::Begin("fastsa", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
ImGui::BeginTable("fastsa", 3, ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_Resizable);
ImGui::TableSetupColumn("SBS laser control", 0, 280.0f);
ImGui::TableSetupColumn("Pump/output heterodyne", 0, 1000.0f);
ImGui::TableSetupColumn("Lineshape", 0, 1000.0f);
ImGui::TableSetupColumn("SBS laser control", 0, 380.0f);
ImGui::TableSetupColumn("Pump/output heterodyne", 0, 1200.0f);
ImGui::TableSetupColumn("Lineshape", 0, 1200.0f);
ImGui::TableHeadersRow();
ImGui::TableNextColumn();
ImGui::Checkbox("Update waterfall plots", &update_wf);
ImGui::Text("Baseband peak: %.3f MHz", (float)freq_peak);
ImGui::Text("TEC current: %.6f mA", (float)tec_current);
ImGui::Text("TEC current: %.3f mA", (float)tec_current*1000.0f);
ImGui::SliderFloat("Setpoint", &freq_setpoint_local, 0.0f, 40.0f);
ImGui::SliderFloat("TEC bias", &tec_bias_local, 0.0f, 0.5f);
ImGui::SliderFloat("TEC P", &tec_p_local, -1.0f, 1.0f);
ImGui::SliderFloat("TEC P", &tec_p_local, -1.0f, 0.0f);
freq_setpoint = freq_setpoint_local;
tec_bias = tec_bias_local;
tec_p = 0.05f*tec_p_local;
tec_p = 0.01f*tec_p_local;
if(ImGui::Button("Exit"))
exit = true;
ImGui::Text("Frames processed: %d", (int)frames_processed);