Compare commits
1 Commits
recorder-s
...
master
Author | SHA1 | Date | |
---|---|---|---|
0c8be8bb27 |
@ -13,3 +13,4 @@ link_directories(/opt/picoscope/lib)
|
|||||||
|
|
||||||
add_subdirectory(src/recorder)
|
add_subdirectory(src/recorder)
|
||||||
add_subdirectory(src/filter)
|
add_subdirectory(src/filter)
|
||||||
|
add_subdirectory(src/awg)
|
||||||
|
7
src/awg/CMakeLists.txt
Normal file
7
src/awg/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
file(GLOB_RECURSE SOURCES "./*.c")
|
||||||
|
add_executable(awg ${SOURCES})
|
||||||
|
target_compile_options(awg PRIVATE -Wall -Wextra)
|
||||||
|
target_link_libraries(awg ps2000)
|
||||||
|
set_target_properties(awg PROPERTIES
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||||
|
)
|
33
src/awg/main.c
Normal file
33
src/awg/main.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#include <libps2000/ps2000.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int16_t unit = ps2000_open_unit();
|
||||||
|
if (unit == -1) {
|
||||||
|
fprintf(stderr, "failed to open a unit!\n");
|
||||||
|
return -1;
|
||||||
|
} else if (unit == 0) {
|
||||||
|
fprintf(stderr, "no units to open!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < 2000; i++) {
|
||||||
|
int16_t err = ps2000_set_sig_gen_built_in(unit, i * 1000, 0, PS2000_DC_VOLTAGE, 0, 0, 0, 0, PS2000_UPDOWN, 0);
|
||||||
|
|
||||||
|
if (err == 0) {
|
||||||
|
printf("failed to set voltage\n");
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "%d\n", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
ps2000_stop(unit);
|
||||||
|
ps2000_close_unit(unit);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
file(GLOB_RECURSE SOURCES "./*.c")
|
file(GLOB_RECURSE SOURCES "./*.c")
|
||||||
add_executable(recorder ${SOURCES})
|
add_executable(recorder ${SOURCES})
|
||||||
target_compile_options(recorder PRIVATE -Wall -Wextra)
|
target_compile_options(recorder PRIVATE -Wall -Wextra)
|
||||||
target_compile_options(recorder PRIVATE -mavx2)
|
|
||||||
target_link_libraries(recorder ps2000)
|
target_link_libraries(recorder ps2000)
|
||||||
set_target_properties(recorder PROPERTIES
|
set_target_properties(recorder PROPERTIES
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
#include <sched.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -20,105 +19,19 @@ void capture_stop(int signal) {
|
|||||||
stop = true;
|
stop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __AVX2__
|
|
||||||
#include <immintrin.h>
|
|
||||||
__always_inline void to_float_iq(const int16_t* i_c, const int16_t* q_c, float* output, uint32_t len) {
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
__m256 scale = _mm256_set1_ps(1.0f / INT16_MAX);
|
|
||||||
for (; i + 16 <= len; i += 16) {
|
|
||||||
// load
|
|
||||||
__m256i i_vec = _mm256_loadu_si256((__m256i*)&i_c[i]);
|
|
||||||
__m256i q_vec = _mm256_loadu_si256((__m256i*)&q_c[i]);
|
|
||||||
|
|
||||||
__m256i i_lo = _mm256_cvtepi16_epi32(_mm256_castsi256_si128(i_vec));
|
|
||||||
__m256i i_hi = _mm256_cvtepi16_epi32(_mm256_extracti128_si256(i_vec, 1));
|
|
||||||
__m256i q_lo = _mm256_cvtepi16_epi32(_mm256_castsi256_si128(q_vec));
|
|
||||||
__m256i q_hi = _mm256_cvtepi16_epi32(_mm256_extracti128_si256(q_vec, 1));
|
|
||||||
|
|
||||||
// convert to float
|
|
||||||
__m256 i_float_lo = _mm256_cvtepi32_ps(i_lo);
|
|
||||||
__m256 i_float_hi = _mm256_cvtepi32_ps(i_hi);
|
|
||||||
__m256 q_float_lo = _mm256_cvtepi32_ps(q_lo);
|
|
||||||
__m256 q_float_hi = _mm256_cvtepi32_ps(q_hi);
|
|
||||||
|
|
||||||
// scale
|
|
||||||
i_float_lo = _mm256_mul_ps(i_float_lo, scale);
|
|
||||||
i_float_hi = _mm256_mul_ps(i_float_hi, scale);
|
|
||||||
q_float_lo = _mm256_mul_ps(q_float_lo, scale);
|
|
||||||
q_float_hi = _mm256_mul_ps(q_float_hi, scale);
|
|
||||||
|
|
||||||
// interleave and store
|
|
||||||
__m256 interleaved_lo0 = _mm256_unpacklo_ps(i_float_lo, q_float_lo);
|
|
||||||
__m256 interleaved_lo1 = _mm256_unpackhi_ps(i_float_lo, q_float_lo);
|
|
||||||
|
|
||||||
__m256 interleaved_hi0 = _mm256_unpacklo_ps(i_float_hi, q_float_hi);
|
|
||||||
__m256 interleaved_hi1 = _mm256_unpackhi_ps(i_float_hi, q_float_hi);
|
|
||||||
|
|
||||||
_mm256_storeu_ps(&output[i * 2 + 0], _mm256_permute2f128_ps(interleaved_lo0, interleaved_lo1, 0x20));
|
|
||||||
_mm256_storeu_ps(&output[i * 2 + 8], _mm256_permute2f128_ps(interleaved_lo0, interleaved_lo1, 0x31));
|
|
||||||
_mm256_storeu_ps(&output[i * 2 + 16], _mm256_permute2f128_ps(interleaved_hi0, interleaved_hi1, 0x20));
|
|
||||||
_mm256_storeu_ps(&output[i * 2 + 24], _mm256_permute2f128_ps(interleaved_hi0, interleaved_hi1, 0x31));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i < len; ++i) {
|
|
||||||
output[i * 2 + 0] = i_c[i] / (float)INT16_MAX;
|
|
||||||
output[i * 2 + 1] = q_c[i] / (float)INT16_MAX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__always_inline void to_float(const int16_t* input, float* output, size_t len) {
|
|
||||||
size_t i = 0;
|
|
||||||
|
|
||||||
__m256 scale = _mm256_set1_ps(1.0f / INT16_MAX);
|
|
||||||
for (; i + 16 <= len; i += 16) {
|
|
||||||
// load
|
|
||||||
__m256i input_vec = _mm256_loadu_si256((__m256i*)&input[i]);
|
|
||||||
|
|
||||||
__m256i input_lo = _mm256_cvtepi16_epi32(_mm256_castsi256_si128(input_vec));
|
|
||||||
__m256i input_hi = _mm256_cvtepi16_epi32(_mm256_extracti128_si256(input_vec, 1));
|
|
||||||
|
|
||||||
// convert to float
|
|
||||||
__m256 float_lo = _mm256_cvtepi32_ps(input_lo);
|
|
||||||
__m256 float_hi = _mm256_cvtepi32_ps(input_hi);
|
|
||||||
|
|
||||||
// scale
|
|
||||||
float_lo = _mm256_mul_ps(float_lo, scale);
|
|
||||||
float_hi = _mm256_mul_ps(float_hi, scale);
|
|
||||||
|
|
||||||
// store
|
|
||||||
_mm256_storeu_ps(&output[i], float_lo);
|
|
||||||
_mm256_storeu_ps(&output[i + 8], float_hi);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; i < len; i++) {
|
|
||||||
output[i] = input[i] / (float)INT16_MAX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void get_overview_buffers(int16_t** overviewBuffers, int16_t overflow, uint32_t triggeredAt, int16_t triggered, int16_t auto_stop, uint32_t nValues) {
|
void get_overview_buffers(int16_t** overviewBuffers, int16_t overflow, uint32_t triggeredAt, int16_t triggered, int16_t auto_stop, uint32_t nValues) {
|
||||||
(void)overflow;
|
(void)overflow;
|
||||||
(void)triggeredAt;
|
(void)triggeredAt;
|
||||||
(void)triggered;
|
(void)triggered;
|
||||||
(void)auto_stop;
|
(void)auto_stop;
|
||||||
|
|
||||||
#ifdef __AVX2__
|
|
||||||
if (cfg->iq_mode) {
|
|
||||||
to_float_iq(overviewBuffers[0], overviewBuffers[2], buffer, nValues);
|
|
||||||
fwrite(buffer, sizeof(float), nValues * 2, stdout);
|
|
||||||
} else {
|
|
||||||
to_float(overviewBuffers[0], buffer, nValues);
|
|
||||||
fwrite(buffer, sizeof(float), nValues, stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
if (cfg->iq_mode) {
|
if (cfg->iq_mode) {
|
||||||
for (uint32_t i = 0; i < nValues; i++) {
|
for (uint32_t i = 0; i < nValues; i++) {
|
||||||
buffer[(i * 2) + 0] = overviewBuffers[0][i] / (float)INT16_MAX;
|
buffer[(i * 2) + 0] = overviewBuffers[0][i] / (float)INT16_MAX;
|
||||||
buffer[(i * 2) + 1] = overviewBuffers[2][i] / (float)INT16_MAX;
|
buffer[(i * 2) + 1] = overviewBuffers[2][i] / (float)INT16_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fprintf(stderr, "%u\n", nValues);
|
||||||
fwrite(buffer, sizeof(float), nValues * 2, stdout);
|
fwrite(buffer, sizeof(float), nValues * 2, stdout);
|
||||||
} else {
|
} else {
|
||||||
for (uint32_t i = 0; i < nValues; i++) {
|
for (uint32_t i = 0; i < nValues; i++) {
|
||||||
@ -127,7 +40,6 @@ void get_overview_buffers(int16_t** overviewBuffers, int16_t overflow, uint32_t
|
|||||||
|
|
||||||
fwrite(buffer, sizeof(float), nValues, stdout);
|
fwrite(buffer, sizeof(float), nValues, stdout);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup(int16_t unit) {
|
void cleanup(int16_t unit) {
|
||||||
@ -181,8 +93,7 @@ int main(int argc, char** argv) {
|
|||||||
buffer = (float*)malloc(sizeof(float) * (cfg->max_buffersize) * (cfg->iq_mode ? 2 : 1));
|
buffer = (float*)malloc(sizeof(float) * (cfg->max_buffersize) * (cfg->iq_mode ? 2 : 1));
|
||||||
|
|
||||||
// start data capture without aggregation
|
// start data capture without aggregation
|
||||||
fprintf(stderr, "sample_interval=%u, time_units=%u, buffer_size=%u, max_buffer_size=%u\n", cfg->sample_interval, cfg->time_units, cfg->buffersize,
|
fprintf(stderr, "sample_interval=%u, time_units=%u, buffer_size=%u, max_buffer_size=%u\n", cfg->sample_interval, cfg->time_units, cfg->buffersize, cfg->max_buffersize);
|
||||||
cfg->max_buffersize);
|
|
||||||
if (ps2000_run_streaming_ns(unit, cfg->sample_interval, cfg->time_units, cfg->buffersize, false, 1, cfg->max_buffersize) == 0) {
|
if (ps2000_run_streaming_ns(unit, cfg->sample_interval, cfg->time_units, cfg->buffersize, false, 1, cfg->max_buffersize) == 0) {
|
||||||
fprintf(stderr, "run_streaming_ns failed!\n");
|
fprintf(stderr, "run_streaming_ns failed!\n");
|
||||||
cleanup(unit);
|
cleanup(unit);
|
||||||
@ -194,7 +105,6 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
while (!stop) {
|
while (!stop) {
|
||||||
ps2000_get_streaming_last_values(unit, &get_overview_buffers);
|
ps2000_get_streaming_last_values(unit, &get_overview_buffers);
|
||||||
sched_yield();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup(unit);
|
cleanup(unit);
|
||||||
|
Loading…
Reference in New Issue
Block a user