kopia lustrzana https://github.com/cariboulabs/cariboulite
Merge branches 'main' and 'main' of https://github.com/cariboulabs/cariboulite
commit
a3b7e6b377
|
@ -22,7 +22,7 @@ def setup_receiver(sdr, channel, freq_hz):
|
||||||
sdr.setGainMode(SOAPY_SDR_RX, channel, use_agc) # Set the gain mode
|
sdr.setGainMode(SOAPY_SDR_RX, channel, use_agc) # Set the gain mode
|
||||||
sdr.setGain(SOAPY_SDR_RX, channel, 0) # Set the gain
|
sdr.setGain(SOAPY_SDR_RX, channel, 0) # Set the gain
|
||||||
sdr.setFrequency(SOAPY_SDR_RX, channel, freq_hz) # Tune the LO
|
sdr.setFrequency(SOAPY_SDR_RX, channel, freq_hz) # Tune the LO
|
||||||
sdr.setBandwidth(SOAPY_SDR_RX, channel, 2.5e6)
|
sdr.setBandwidth(SOAPY_SDR_RX, channel, 2500e5)
|
||||||
rx_stream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [channel]) # Setup data stream
|
rx_stream = sdr.setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, [channel]) # Setup data stream
|
||||||
return rx_stream
|
return rx_stream
|
||||||
|
|
||||||
|
@ -77,4 +77,4 @@ plt.show()
|
||||||
fig = plt.figure()
|
fig = plt.figure()
|
||||||
plt.plot(s_real)
|
plt.plot(s_real)
|
||||||
plt.plot(s_imag)
|
plt.plot(s_imag)
|
||||||
plt.show()
|
plt.show()
|
Plik diff jest za duży
Load Diff
|
@ -20,15 +20,13 @@ module lvds_rx
|
||||||
localparam
|
localparam
|
||||||
modem_i_sync = 3'b10,
|
modem_i_sync = 3'b10,
|
||||||
modem_q_sync = 3'b01;
|
modem_q_sync = 3'b01;
|
||||||
// modem_i_sync = 3'b01,
|
|
||||||
// modem_q_sync = 3'b10;
|
|
||||||
|
|
||||||
// Internal Registers
|
// Internal Registers
|
||||||
reg [1:0] r_state_if;
|
reg [1:0] r_state_if;
|
||||||
reg [2:0] r_phase_count;
|
reg [2:0] r_phase_count;
|
||||||
reg [31:0] r_data;
|
reg [31:0] r_data;
|
||||||
reg r_push;
|
reg r_push;
|
||||||
reg [1:0] r_cnt;
|
reg r_cnt;
|
||||||
|
|
||||||
assign o_debug_state = r_state_if;
|
assign o_debug_state = r_state_if;
|
||||||
|
|
||||||
|
@ -64,39 +62,35 @@ module lvds_rx
|
||||||
end
|
end
|
||||||
|
|
||||||
r_phase_count <= 3'b111;
|
r_phase_count <= 3'b111;
|
||||||
|
r_data <= 0;
|
||||||
r_push <= 1'b0;
|
r_push <= 1'b0;
|
||||||
r_data[3:2] <= 2'b11;
|
|
||||||
r_data[1:0] <= r_cnt;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
state_i_phase: begin
|
state_i_phase: begin
|
||||||
if (r_phase_count == 3'b000) begin
|
if (r_phase_count == 3'b000) begin
|
||||||
if (i_ddr_data == modem_q_sync ) begin
|
if (i_ddr_data == modem_q_sync ) begin
|
||||||
r_phase_count <= 3'b111;
|
r_phase_count <= 3'b110;
|
||||||
r_state_if <= state_q_phase;
|
r_state_if <= state_q_phase;
|
||||||
end else begin
|
end else begin
|
||||||
r_state_if <= state_idle;
|
r_state_if <= state_idle;
|
||||||
end
|
end
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
r_phase_count <= r_phase_count - 1;
|
r_phase_count <= r_phase_count - 1;
|
||||||
r_data <= {r_data[29:0], i_ddr_data};
|
|
||||||
end
|
end
|
||||||
|
|
||||||
//r_data <= {r_data[29:0], i_ddr_data};
|
r_data <= {r_data[29:0], i_ddr_data};
|
||||||
end
|
end
|
||||||
|
|
||||||
state_q_phase: begin
|
state_q_phase: begin
|
||||||
if (r_phase_count == 3'b000) begin
|
if (r_phase_count == 3'b000) begin
|
||||||
r_push <= ~i_fifo_full;
|
r_push <= ~i_fifo_full;
|
||||||
r_state_if <= state_idle;
|
r_state_if <= state_idle;
|
||||||
//o_fifo_data <= {r_data[29:0], i_ddr_data};
|
o_fifo_data <= {r_data[29:0], i_ddr_data};
|
||||||
o_fifo_data <= r_data;
|
|
||||||
r_cnt <= r_cnt + 1;
|
|
||||||
end else begin
|
end else begin
|
||||||
r_phase_count <= r_phase_count - 1;
|
r_phase_count <= r_phase_count - 1;
|
||||||
r_data <= {r_data[29:0], i_ddr_data};
|
|
||||||
end
|
end
|
||||||
//r_data <= {r_data[29:0], i_ddr_data};
|
r_data <= {r_data[29:0], i_ddr_data};
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
18265
firmware/top.asc
18265
firmware/top.asc
Plik diff jest za duży
Load Diff
BIN
firmware/top.bin
BIN
firmware/top.bin
Plik binarny nie jest wyświetlany.
20911
firmware/top.json
20911
firmware/top.json
Plik diff jest za duży
Load Diff
|
@ -45,6 +45,87 @@ static void caribou_smi_print_smi_settings(caribou_smi_st* dev, struct smi_setti
|
||||||
static void caribou_smi_setup_settings (caribou_smi_st* dev, struct smi_settings *settings);
|
static void caribou_smi_setup_settings (caribou_smi_st* dev, struct smi_settings *settings);
|
||||||
static void caribou_smi_init_stream(caribou_smi_st* dev, caribou_smi_stream_type_en type, caribou_smi_channel_en ch);
|
static void caribou_smi_init_stream(caribou_smi_st* dev, caribou_smi_stream_type_en type, caribou_smi_channel_en ch);
|
||||||
|
|
||||||
|
|
||||||
|
#define TIMING_PERF_SYNC (0)
|
||||||
|
|
||||||
|
#if (TIMING_PERF_SYNC)
|
||||||
|
#define TIMING_PERF_SYNC_VARS \
|
||||||
|
struct timeval tv_pre = {0}; \
|
||||||
|
struct timeval tv_post = {0}; \
|
||||||
|
long long total_samples = 0,last_total_samples = 0; \
|
||||||
|
double time_pre = 0, batch_time = 0, sample_rate = 0; \
|
||||||
|
double time_post = 0, process_time = 0; \
|
||||||
|
double temp_pre; \
|
||||||
|
double num_samples = 0, num_samples_avg = 0;
|
||||||
|
|
||||||
|
#define TIMING_PERF_SYNC_TICK \
|
||||||
|
gettimeofday(&tv_pre, NULL);
|
||||||
|
|
||||||
|
#define TIMING_PERF_SYNC_TOCK \
|
||||||
|
gettimeofday(&tv_post, NULL); \
|
||||||
|
num_samples = (double)(st->read_ret_value) / 4.0; \
|
||||||
|
num_samples_avg = num_samples_avg*0.1 + num_samples*0.9; \
|
||||||
|
temp_pre = tv_pre.tv_sec + ((double)(tv_pre.tv_usec)) / 1e6; \
|
||||||
|
time_post = tv_post.tv_sec + ((double)(tv_post.tv_usec)) / 1e6; \
|
||||||
|
batch_time = temp_pre - time_pre; \
|
||||||
|
sample_rate = sample_rate*0.1 + (num_samples / batch_time) * 0.9; \
|
||||||
|
process_time = process_time*0.1 + (time_post - temp_pre)*0.9; \
|
||||||
|
time_pre = temp_pre; \
|
||||||
|
total_samples += st->read_ret_value; \
|
||||||
|
if ((total_samples - last_total_samples) > 4000000*4) \
|
||||||
|
{ \
|
||||||
|
last_total_samples = total_samples; \
|
||||||
|
ZF_LOGD("sample_rate = %.2f SPS, process_time = %.2f usec" \
|
||||||
|
", num_samples_avg = %.1f", \
|
||||||
|
sample_rate, process_time * 1e6, num_samples_avg); \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define TIMING_PERF_SYNC_VARS
|
||||||
|
#define TIMING_PERF_SYNC_TICK
|
||||||
|
#define TIMING_PERF_SYNC_TOCK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
void dump_hex(const void* data, size_t size)
|
||||||
|
{
|
||||||
|
char ascii[17];
|
||||||
|
size_t i, j;
|
||||||
|
ascii[16] = '\0';
|
||||||
|
|
||||||
|
for (i = 0; i < size; ++i) {
|
||||||
|
printf("%02X ", ((unsigned char*)data)[i]);
|
||||||
|
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~')
|
||||||
|
{
|
||||||
|
ascii[i % 16] = ((unsigned char*)data)[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ascii[i % 16] = '.';
|
||||||
|
}
|
||||||
|
if ((i+1) % 8 == 0 || i+1 == size)
|
||||||
|
{
|
||||||
|
printf(" ");
|
||||||
|
if ((i+1) % 16 == 0)
|
||||||
|
{
|
||||||
|
printf("| %s \n", ascii);
|
||||||
|
}
|
||||||
|
else if (i+1 == size)
|
||||||
|
{
|
||||||
|
ascii[(i+1) % 16] = '\0';
|
||||||
|
if ((i+1) % 16 <= 8)
|
||||||
|
{
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
for (j = (i+1) % 16; j < 16; ++j)
|
||||||
|
{
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
printf("| %s \n", ascii);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
char* caribou_smi_get_error_string(caribou_smi_error_en err)
|
char* caribou_smi_get_error_string(caribou_smi_error_en err)
|
||||||
{
|
{
|
||||||
|
@ -131,49 +212,6 @@ int caribou_smi_close (caribou_smi_st* dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
int caribou_smi_read_async(
|
|
||||||
caribou_smi_st* dev,
|
|
||||||
caribou_smi_address_en source,
|
|
||||||
char* buffer,
|
|
||||||
int size_of_buf,
|
|
||||||
struct aiocb *read_aiocb)
|
|
||||||
{
|
|
||||||
// set the address
|
|
||||||
if (source > 0 && CARIBOU_SMI_READ_ADDR(source))
|
|
||||||
{
|
|
||||||
if (source != dev->current_address)
|
|
||||||
{
|
|
||||||
int ret = ioctl(dev->filedesc, BCM2835_SMI_IOC_ADDRESS, source);
|
|
||||||
if (ret != 0)
|
|
||||||
{
|
|
||||||
ZF_LOGE("failed setting smi address (idle / %d) to device", source);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
printf("Set address to %d\n", source);
|
|
||||||
dev->current_address = source;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ZF_LOGE("the specified address is not a read address (%d)", source);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bzero((char *)read_aiocb, sizeof(struct aiocb));
|
|
||||||
read_aiocb->aio_buf = buffer;
|
|
||||||
read_aiocb->aio_fildes = dev->filedesc;
|
|
||||||
read_aiocb->aio_nbytes = size_of_buf;
|
|
||||||
read_aiocb->aio_offset = 0;
|
|
||||||
int ret = aio_read(read_aiocb);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
printf("aio_read failed!!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
int caribou_smi_timeout_read(caribou_smi_st* dev,
|
int caribou_smi_timeout_read(caribou_smi_st* dev,
|
||||||
caribou_smi_address_en source,
|
caribou_smi_address_en source,
|
||||||
|
@ -348,6 +386,7 @@ static void set_realtime_priority(int priority_deter)
|
||||||
ZF_LOGI("Thread priority is %d", params.sched_priority);
|
ZF_LOGI("Thread priority is %d", params.sched_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
int caribou_smi_search_offset(uint8_t *buff, int len)
|
int caribou_smi_search_offset(uint8_t *buff, int len)
|
||||||
{
|
{
|
||||||
bool succ = false;
|
bool succ = false;
|
||||||
|
@ -365,24 +404,131 @@ int caribou_smi_search_offset(uint8_t *buff, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
#define TIMING_PERF_SYNC (0)
|
/*void caribou_smi_convert_data(uint8_t *buffer,
|
||||||
|
size_t length_bytes,
|
||||||
|
caribou_smi_sample_complex_int16* cmplx_vec,
|
||||||
|
caribou_smi_sample_meta* meta_vec)
|
||||||
|
{
|
||||||
|
static bool ptr = true;
|
||||||
|
|
||||||
|
// the verilog struct looks as follows:
|
||||||
|
// [ 31:30 ] [ 29:28 ] [ 27:15 ] [ 14 ] [ 13:1 ] [ 0 ]
|
||||||
|
// [always "11"] [ CNT 2Bits ] [ I sample ] [ SYNC1 ] [ Q sample ] [ SYNC2 ]
|
||||||
|
|
||||||
|
uint32_t *samples = (uint32_t*)buffer;
|
||||||
|
//uint32_t cnt_gaps = 0;
|
||||||
|
int num_sync_errors = 0;
|
||||||
|
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
dump_hex(buffer, 64);
|
||||||
|
for (int k = 0; k < 8; k ++)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("0x%08X, \n", __builtin_bswap32(samples[k]));
|
||||||
|
}
|
||||||
|
//ptr = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < length_bytes/4; i++)
|
||||||
|
{
|
||||||
|
uint32_t s = __builtin_bswap32(samples[i]);
|
||||||
|
|
||||||
|
meta_vec[i].sync2 = s & 0x00000001; s >>= 1;
|
||||||
|
cmplx_vec[i].q = s & 0x00001FFF; s >>= 13;
|
||||||
|
meta_vec[i].sync1 = s & 0x00000001; s >>= 1;
|
||||||
|
cmplx_vec[i].i = s & 0x00001FFF; s >>= 13;
|
||||||
|
meta_vec[i].cnt = s & 0x00000003; s >>= 2;
|
||||||
|
if (s != 0x3)
|
||||||
|
{
|
||||||
|
num_sync_errors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmplx_vec[i].i >= (int16_t)0x1000) cmplx_vec[i].i -= (int16_t)0x2000;
|
||||||
|
if (cmplx_vec[i].q >= (int16_t)0x1000) cmplx_vec[i].q -= (int16_t)0x2000;
|
||||||
|
|
||||||
|
// TODO: calculate the cnt gaps
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 64; k ++)
|
||||||
|
{
|
||||||
|
printf("(%d, %d), sync = [%d,%d]\n", cmplx_vec[k].i, cmplx_vec[k].q, meta_vec[k].sync1, meta_vec[k].sync2);
|
||||||
|
}
|
||||||
|
ptr = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (num_sync_errors) printf("caribou_smi_convert_data: sync errors @ %d samples\n", num_sync_errors);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
void caribou_smi_convert_data(uint8_t *buffer,
|
||||||
|
size_t length_bytes,
|
||||||
|
caribou_smi_sample_complex_int16* cmplx_vec,
|
||||||
|
caribou_smi_sample_meta* meta_vec)
|
||||||
|
{
|
||||||
|
static bool ptr = true;
|
||||||
|
|
||||||
|
// the verilog struct looks as follows:
|
||||||
|
// [31:30] [ 29:17 ] [ 16 ] [ 15:14 ] [ 13:1 ] [ 0 ]
|
||||||
|
// [ '00'] [ I sample ] [ '0' ] [ '01' ] [ Q sample ] [ '0' ]
|
||||||
|
|
||||||
|
uint32_t *samples = (uint32_t*)buffer;
|
||||||
|
//uint32_t cnt_gaps = 0;
|
||||||
|
int num_sync_errors = 0;
|
||||||
|
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
printf("got byte array with %d bytes\n", length_bytes);
|
||||||
|
dump_hex(buffer, 64);
|
||||||
|
for (int k = 0; k < 8; k ++)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("0x%08X, \n", (samples[k]));
|
||||||
|
}
|
||||||
|
//ptr = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < length_bytes/4; i++)
|
||||||
|
{
|
||||||
|
uint32_t s = (samples[i]);
|
||||||
|
|
||||||
|
/*meta_vec[i].sync2 = s & 0x00000001; */s >>= 1;
|
||||||
|
cmplx_vec[i].q = s & 0x00001FFF; s >>= 13;
|
||||||
|
s >>= 2;
|
||||||
|
/*meta_vec[i].sync1 = s & 0x00000001; */s >>= 1;
|
||||||
|
cmplx_vec[i].i = s & 0x00001FFF; s >>= 13;
|
||||||
|
//meta_vec[i].cnt = s & 0x00000003; s >>= 2;
|
||||||
|
if (s != 0x0)
|
||||||
|
{
|
||||||
|
num_sync_errors++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmplx_vec[i].i >= (int16_t)0x1000) cmplx_vec[i].i -= (int16_t)0x2000;
|
||||||
|
if (cmplx_vec[i].q >= (int16_t)0x1000) cmplx_vec[i].q -= (int16_t)0x2000;
|
||||||
|
|
||||||
|
// TODO: calculate the cnt gaps
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 64; k ++)
|
||||||
|
{
|
||||||
|
printf("(%d, %d), sync = [%d,%d]\n", cmplx_vec[k].i, cmplx_vec[k].q, meta_vec[k].sync1, meta_vec[k].sync2);
|
||||||
|
}
|
||||||
|
ptr = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (num_sync_errors) printf("caribou_smi_convert_data: sync errors @ %d samples\n", num_sync_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
void* caribou_smi_analyze_thread(void* arg)
|
void* caribou_smi_analyze_thread(void* arg)
|
||||||
{
|
{
|
||||||
//static int a = 0;
|
//static int a = 0;
|
||||||
int current_data_size = 0;
|
int current_data_size = 0;
|
||||||
pthread_t tid = pthread_self();
|
pthread_t tid = pthread_self();
|
||||||
|
TIMING_PERF_SYNC_VARS;
|
||||||
// --------------------------------------------
|
|
||||||
// TIMING PERF VARIABLES
|
|
||||||
#if (TIMING_PERF_SYNC)
|
|
||||||
struct timeval tv_pre = {0};
|
|
||||||
struct timeval tv_post = {0};
|
|
||||||
long long total_samples = 0;
|
|
||||||
double time_pre = 0, batch_time = 0, sample_rate = 0;
|
|
||||||
double time_post = 0, process_time = 0;
|
|
||||||
double temp_pre;
|
|
||||||
double num_samples = 0, num_samples_avg = 0;
|
|
||||||
#endif // TIMING_PERF_SYNC
|
|
||||||
|
|
||||||
caribou_smi_stream_st* st = (caribou_smi_stream_st*)arg;
|
caribou_smi_stream_st* st = (caribou_smi_stream_st*)arg;
|
||||||
caribou_smi_st* dev = (caribou_smi_st*)st->parent_dev;
|
caribou_smi_st* dev = (caribou_smi_st*)st->parent_dev;
|
||||||
|
@ -393,56 +539,36 @@ void* caribou_smi_analyze_thread(void* arg)
|
||||||
set_realtime_priority(2);
|
set_realtime_priority(2);
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
// ****************************************
|
||||||
|
// MAIN LOOP
|
||||||
|
// ****************************************
|
||||||
while (st->read_analysis_thread_running)
|
while (st->read_analysis_thread_running)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&st->read_analysis_lock);
|
pthread_mutex_lock(&st->read_analysis_lock);
|
||||||
|
TIMING_PERF_SYNC_TICK;
|
||||||
#if (TIMING_PERF_SYNC)
|
|
||||||
gettimeofday(&tv_pre, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!st->read_analysis_thread_running) break;
|
if (!st->read_analysis_thread_running) break;
|
||||||
|
|
||||||
offset = caribou_smi_search_offset(st->current_app_buffer, 16);
|
/*offset = caribou_smi_search_offset(st->current_app_buffer, 16);
|
||||||
if (offset == -1)
|
if (offset == -1)
|
||||||
{
|
{
|
||||||
ZF_LOGE("Offset error!");
|
ZF_LOGE("Offset error!");
|
||||||
for (int i = 0; i < 60; i+=4)
|
dump_hex(st->current_app_buffer, 60);
|
||||||
{
|
}*/
|
||||||
printf("%08X\n", *((uint32_t*)(st->current_app_buffer + i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current_data_size = st->read_ret_value;
|
current_data_size = st->read_ret_value;
|
||||||
if (offset != 0) current_data_size -= 4;
|
//if (offset != 0) current_data_size -= 4;
|
||||||
|
|
||||||
if (st->data_cb) st->data_cb(dev->cb_context,
|
caribou_smi_convert_data(st->current_app_buffer + offset,
|
||||||
st->service_context,
|
current_data_size,
|
||||||
type,
|
st->app_cmplx_vec,
|
||||||
ch,
|
st->app_meta_vec);
|
||||||
current_data_size,
|
|
||||||
st->current_app_buffer + offset,
|
if (st->data_cb) st->data_cb(dev->cb_context, st->service_context, type, ch,
|
||||||
st->batch_length);
|
current_data_size / 4,
|
||||||
|
st->app_cmplx_vec,
|
||||||
|
st->app_meta_vec,
|
||||||
|
st->batch_length / 4);
|
||||||
|
|
||||||
#if (TIMING_PERF_SYNC)
|
TIMING_PERF_SYNC_TOCK;
|
||||||
gettimeofday(&tv_post, NULL);
|
|
||||||
|
|
||||||
// benchmarking
|
|
||||||
num_samples = (double)(st->read_ret_value) / 4.0;
|
|
||||||
num_samples_avg = num_samples_avg*0.1 + num_samples*0.9;
|
|
||||||
temp_pre = tv_pre.tv_sec + ((double)(tv_pre.tv_usec)) / 1e6;
|
|
||||||
time_post = tv_post.tv_sec + ((double)(tv_post.tv_usec)) / 1e6;
|
|
||||||
|
|
||||||
batch_time = temp_pre - time_pre;
|
|
||||||
sample_rate = sample_rate*0.1 + (num_samples / batch_time) * 0.9;
|
|
||||||
process_time = process_time*0.1 + (time_post - temp_pre)*0.9;
|
|
||||||
|
|
||||||
time_pre = temp_pre;
|
|
||||||
total_samples += st->read_ret_value;
|
|
||||||
if (total_samples % (4*4000000) == 0)
|
|
||||||
{
|
|
||||||
printf("sample_rate = %.2f SPS, process_time = %.2f usec, num_samples_avg = %.1f\n", sample_rate, process_time * 1e6, num_samples_avg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZF_LOGD("Leaving SMI analysis thread id %lu, running = %d", tid, st->read_analysis_thread_running);
|
ZF_LOGD("Leaving SMI analysis thread id %lu, running = %d", tid, st->read_analysis_thread_running);
|
||||||
|
@ -452,24 +578,11 @@ void* caribou_smi_analyze_thread(void* arg)
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
void* caribou_smi_thread(void *arg)
|
void* caribou_smi_thread(void *arg)
|
||||||
{
|
{
|
||||||
// --------------------------------------------
|
TIMING_PERF_SYNC_VARS;
|
||||||
// TIMING PERF VARIABLES
|
|
||||||
#if (TIMING_PERF_SYNC)
|
|
||||||
struct timeval tv_pre = {0};
|
|
||||||
struct timeval tv_post = {0};
|
|
||||||
long long total_samples = 0;
|
|
||||||
long long last_total_samples = 0;
|
|
||||||
double time_pre = 0, batch_time = 0, sample_rate = 0;
|
|
||||||
double time_post = 0, process_time = 0;
|
|
||||||
double temp_pre;
|
|
||||||
double num_samples = 0, num_samples_avg = 0;
|
|
||||||
#endif // TIMING_PERF_SYNC
|
|
||||||
// --------------------------------------------
|
|
||||||
|
|
||||||
pthread_t tid = pthread_self();
|
pthread_t tid = pthread_self();
|
||||||
caribou_smi_stream_st* st = (caribou_smi_stream_st*)arg;
|
caribou_smi_stream_st* st = (caribou_smi_stream_st*)arg;
|
||||||
caribou_smi_st* dev = (caribou_smi_st*)st->parent_dev;
|
caribou_smi_st* dev = (caribou_smi_st*)st->parent_dev;
|
||||||
//caribou_smi_stream_type_en type = (caribou_smi_stream_type_en)(st->stream_id>>1 & 0x1);
|
|
||||||
caribou_smi_channel_en ch = (caribou_smi_channel_en)(st->stream_id & 0x1);
|
caribou_smi_channel_en ch = (caribou_smi_channel_en)(st->stream_id & 0x1);
|
||||||
|
|
||||||
ZF_LOGD("Entered thread id %lu, running = %d, Perf-Verbosity = %d", tid, st->running, TIMING_PERF_SYNC);
|
ZF_LOGD("Entered thread id %lu, running = %d, Perf-Verbosity = %d", tid, st->running, TIMING_PERF_SYNC);
|
||||||
|
@ -498,13 +611,11 @@ void* caribou_smi_thread(void *arg)
|
||||||
|
|
||||||
// start thread notification
|
// start thread notification
|
||||||
if (st->data_cb != NULL) st->data_cb(dev->cb_context, st->service_context,
|
if (st->data_cb != NULL) st->data_cb(dev->cb_context, st->service_context,
|
||||||
caribou_smi_stream_start,
|
caribou_smi_stream_start, ch, 0, NULL, NULL, 0);
|
||||||
ch,
|
|
||||||
0,
|
|
||||||
st->current_app_buffer,
|
|
||||||
st->batch_length);
|
|
||||||
|
|
||||||
// thread main loop
|
// ****************************************
|
||||||
|
// MAIN LOOP
|
||||||
|
// ****************************************
|
||||||
while (st->active)
|
while (st->active)
|
||||||
{
|
{
|
||||||
if (!st->running)
|
if (!st->running)
|
||||||
|
@ -513,12 +624,7 @@ void* caribou_smi_thread(void *arg)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------
|
TIMING_PERF_SYNC_TICK;
|
||||||
// TIMING PERF
|
|
||||||
#if (TIMING_PERF_SYNC)
|
|
||||||
gettimeofday(&tv_pre, NULL);
|
|
||||||
#endif // TIMING_PERF_SYNC
|
|
||||||
// --------------------------------------------
|
|
||||||
|
|
||||||
int ret = caribou_smi_timeout_read(dev, st->addr, (char*)st->current_smi_buffer, st->batch_length, 200);
|
int ret = caribou_smi_timeout_read(dev, st->addr, (char*)st->current_smi_buffer, st->batch_length, 200);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -546,30 +652,7 @@ void* caribou_smi_thread(void *arg)
|
||||||
if (st->current_smi_buffer_index >= (int)(st->num_of_buffers)) st->current_smi_buffer_index = 0;
|
if (st->current_smi_buffer_index >= (int)(st->num_of_buffers)) st->current_smi_buffer_index = 0;
|
||||||
st->current_smi_buffer = st->buffers[st->current_smi_buffer_index];
|
st->current_smi_buffer = st->buffers[st->current_smi_buffer_index];
|
||||||
|
|
||||||
// --------------------------------------------
|
TIMING_PERF_SYNC_TOCK;
|
||||||
// TIMING PERF
|
|
||||||
#if (TIMING_PERF_SYNC)
|
|
||||||
gettimeofday(&tv_post, NULL);
|
|
||||||
num_samples = (double)(st->read_ret_value) / 4.0;
|
|
||||||
num_samples_avg = num_samples_avg*0.1 + num_samples*0.9;
|
|
||||||
temp_pre = tv_pre.tv_sec + ((double)(tv_pre.tv_usec)) / 1e6;
|
|
||||||
time_post = tv_post.tv_sec + ((double)(tv_post.tv_usec)) / 1e6;
|
|
||||||
|
|
||||||
batch_time = temp_pre - time_pre;
|
|
||||||
sample_rate = sample_rate*0.1 + (num_samples / batch_time) * 0.9;
|
|
||||||
process_time = process_time*0.1 + (time_post - temp_pre)*0.9;
|
|
||||||
|
|
||||||
time_pre = temp_pre;
|
|
||||||
total_samples += st->read_ret_value;
|
|
||||||
if ((total_samples - last_total_samples) > 4000000*4)
|
|
||||||
{
|
|
||||||
last_total_samples = total_samples;
|
|
||||||
ZF_LOGD("sample_rate = %.2f SPS, process_time = %.2f usec"
|
|
||||||
", num_samples_avg = %.1f",
|
|
||||||
sample_rate, process_time * 1e6, num_samples_avg);
|
|
||||||
}
|
|
||||||
#endif // TIMING_PERF_SYNC
|
|
||||||
// --------------------------------------------
|
|
||||||
}
|
}
|
||||||
|
|
||||||
st->read_analysis_thread_running = 0;
|
st->read_analysis_thread_running = 0;
|
||||||
|
@ -578,153 +661,14 @@ void* caribou_smi_thread(void *arg)
|
||||||
pthread_mutex_destroy(&st->read_analysis_lock);
|
pthread_mutex_destroy(&st->read_analysis_lock);
|
||||||
|
|
||||||
// exit thread notification
|
// exit thread notification
|
||||||
if (st->data_cb != NULL) st->data_cb(dev->cb_context,
|
if (st->data_cb != NULL) st->data_cb(dev->cb_context, st->service_context,
|
||||||
st->service_context,
|
caribou_smi_stream_end, (caribou_smi_channel_en)(st->stream_id>>1),
|
||||||
caribou_smi_stream_end,
|
0, NULL, NULL, 0);
|
||||||
(caribou_smi_channel_en)(st->stream_id>>1),
|
|
||||||
0,
|
|
||||||
st->current_app_buffer,
|
|
||||||
st->batch_length);
|
|
||||||
|
|
||||||
ZF_LOGD("Leaving thread id %lu", tid);
|
ZF_LOGD("Leaving thread id %lu", tid);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*#define TIMING_PERF_ASYNC (1)
|
|
||||||
//=========================================================================
|
|
||||||
void* caribou_smi_thread_async(void *arg)
|
|
||||||
{
|
|
||||||
// --------------------------------------------
|
|
||||||
// TIMING PERF VARIABLES
|
|
||||||
#if (TIMING_PERF_ASYNC)
|
|
||||||
struct timeval tv_pre = {0};
|
|
||||||
struct timeval tv_post = {0};
|
|
||||||
long long total_samples = 0;
|
|
||||||
double time_pre = 0, batch_time = 0, sample_rate = 0;
|
|
||||||
double time_post = 0, process_time = 0;
|
|
||||||
double temp_pre;
|
|
||||||
double num_samples = 0, num_samples_avg = 0;
|
|
||||||
#endif // TIMING_PERF_ASYNC
|
|
||||||
// --------------------------------------------
|
|
||||||
|
|
||||||
pthread_t tid = pthread_self();
|
|
||||||
struct aiocb read_aiocb = {0};
|
|
||||||
caribou_smi_stream_st* st = (caribou_smi_stream_st*)arg;
|
|
||||||
caribou_smi_st* dev = (caribou_smi_st*)st->parent_dev;
|
|
||||||
caribou_smi_stream_type_en type = (caribou_smi_stream_type_en)(st->stream_id>>1 & 0x1);
|
|
||||||
caribou_smi_channel_en ch = (caribou_smi_channel_en)(st->stream_id & 0x1);
|
|
||||||
|
|
||||||
ZF_LOGD("Entered thread id %lu, running = %d", tid, st->running);
|
|
||||||
set_realtime_priority(0);
|
|
||||||
|
|
||||||
st->active = 1;
|
|
||||||
|
|
||||||
// start thread notification
|
|
||||||
if (st->data_cb != NULL) st->data_cb(dev->cb_context, st->service_context,
|
|
||||||
caribou_smi_stream_start,
|
|
||||||
ch,
|
|
||||||
0,
|
|
||||||
st->current_app_buffer,
|
|
||||||
st->batch_length);
|
|
||||||
|
|
||||||
// -------------------------------
|
|
||||||
// THREAD MAIN LOOP
|
|
||||||
// -------------------------------
|
|
||||||
while (st->active)
|
|
||||||
{
|
|
||||||
if (!st->running)
|
|
||||||
{
|
|
||||||
usleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------
|
|
||||||
// TIMING PERF
|
|
||||||
#if (TIMING_PERF_ASYNC)
|
|
||||||
gettimeofday(&tv_pre, NULL);
|
|
||||||
#endif // TIMING_PERF_ASYNC
|
|
||||||
// --------------------------------------------
|
|
||||||
|
|
||||||
// Run the async read
|
|
||||||
// This operation doesn't block and returns immediatelly
|
|
||||||
// in the meantime we do other stuff and some back
|
|
||||||
// to get the results later.
|
|
||||||
int ret = caribou_smi_read_async(dev, st->addr,
|
|
||||||
(char*)st->current_smi_buffer,
|
|
||||||
st->batch_length,
|
|
||||||
&read_aiocb);
|
|
||||||
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
ZF_LOGE("async read failed");
|
|
||||||
if (dev->error_cb) dev->error_cb(dev->cb_context, st->stream_id & 0x1, caribou_smi_error_read_failed);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// analyze the last buffer that was accepted
|
|
||||||
if (st->current_app_buffer)
|
|
||||||
{
|
|
||||||
if (st->data_cb) st->data_cb(dev->cb_context,
|
|
||||||
st->service_context,
|
|
||||||
type,
|
|
||||||
ch,
|
|
||||||
st->read_ret_value,
|
|
||||||
st->current_app_buffer,
|
|
||||||
st->batch_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------
|
|
||||||
// TIMING PERF
|
|
||||||
#if (TIMING_PERF_ASYNC)
|
|
||||||
gettimeofday(&tv_post, NULL);
|
|
||||||
num_samples = (double)(st->read_ret_value) / 4.0;
|
|
||||||
num_samples_avg = num_samples_avg*0.1 + num_samples*0.9;
|
|
||||||
temp_pre = tv_pre.tv_sec + ((double)(tv_pre.tv_usec)) / 1e6;
|
|
||||||
time_post = tv_post.tv_sec + ((double)(tv_post.tv_usec)) / 1e6;
|
|
||||||
|
|
||||||
batch_time = temp_pre - time_pre;
|
|
||||||
sample_rate = sample_rate*0.1 + (num_samples / batch_time) * 0.9;
|
|
||||||
process_time = process_time*0.1 + (time_post - temp_pre)*0.9;
|
|
||||||
|
|
||||||
time_pre = temp_pre;
|
|
||||||
total_samples += st->read_ret_value;
|
|
||||||
if (total_samples % (4*4000000) == 0)
|
|
||||||
{
|
|
||||||
printf("sample_rate = %.2f SPS, process_time = %.2f usec"
|
|
||||||
", num_samples_avg = %.1f\n",
|
|
||||||
sample_rate, process_time * 1e6, num_samples_avg);
|
|
||||||
}
|
|
||||||
#endif // TIMING_PERF_ASYNC
|
|
||||||
// --------------------------------------------
|
|
||||||
|
|
||||||
// wait for the async to complete
|
|
||||||
struct aiocb* read_aiocb_vec[1];
|
|
||||||
read_aiocb_vec[0] = &read_aiocb;
|
|
||||||
ret = aio_suspend(read_aiocb_vec, 1, NULL);
|
|
||||||
if (ret >= 0)
|
|
||||||
{
|
|
||||||
st->read_ret_value = st->batch_length;
|
|
||||||
st->current_app_buffer = st->current_smi_buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
st->current_smi_buffer_index ++;
|
|
||||||
if (st->current_smi_buffer_index >= (int)(st->num_of_buffers)) st->current_smi_buffer_index = 0;
|
|
||||||
st->current_smi_buffer = st->buffers[st->current_smi_buffer_index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// exit thread notification
|
|
||||||
if (st->data_cb != NULL) st->data_cb(dev->cb_context,
|
|
||||||
st->service_context,
|
|
||||||
caribou_smi_stream_end,
|
|
||||||
(caribou_smi_channel_en)(st->stream_id>>1),
|
|
||||||
0,
|
|
||||||
st->current_app_buffer,
|
|
||||||
st->batch_length);
|
|
||||||
|
|
||||||
ZF_LOGD("Leaving thread id %lu", tid);
|
|
||||||
return NULL;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
static int caribou_smi_set_driver_streaming_state(caribou_smi_st* dev, int state)
|
static int caribou_smi_set_driver_streaming_state(caribou_smi_st* dev, int state)
|
||||||
{
|
{
|
||||||
|
@ -753,8 +697,10 @@ int caribou_smi_setup_stream(caribou_smi_st* dev,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
st->app_meta_vec = NULL;
|
||||||
|
st->app_cmplx_vec = NULL;
|
||||||
st->batch_length = dev->native_batch_length_bytes;
|
st->batch_length = dev->native_batch_length_bytes;
|
||||||
st->num_of_buffers = 3;
|
st->num_of_buffers = 2;
|
||||||
st->data_cb = cb;
|
st->data_cb = cb;
|
||||||
|
|
||||||
caribou_smi_set_driver_streaming_state(dev, 0);
|
caribou_smi_set_driver_streaming_state(dev, 0);
|
||||||
|
@ -766,6 +712,26 @@ int caribou_smi_setup_stream(caribou_smi_st* dev,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate the complex vector and metadata vector
|
||||||
|
st->app_cmplx_vec =
|
||||||
|
(caribou_smi_sample_complex_int16*)malloc(sizeof(caribou_smi_sample_complex_int16) * st->batch_length / 4);
|
||||||
|
if (st->app_cmplx_vec == NULL)
|
||||||
|
{
|
||||||
|
ZF_LOGE("application complex buffer allocation failed");
|
||||||
|
release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
st->app_meta_vec =
|
||||||
|
(caribou_smi_sample_meta*)malloc(sizeof(caribou_smi_sample_meta) * st->batch_length / 4);
|
||||||
|
if (st->app_meta_vec == NULL)
|
||||||
|
{
|
||||||
|
ZF_LOGE("application meta-data buffer allocation failed");
|
||||||
|
release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
||||||
|
free(st->app_cmplx_vec);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
st->current_smi_buffer_index = 0;
|
st->current_smi_buffer_index = 0;
|
||||||
st->current_smi_buffer = st->buffers[0];
|
st->current_smi_buffer = st->buffers[0];
|
||||||
st->current_app_buffer = st->buffers[st->num_of_buffers-1];
|
st->current_app_buffer = st->buffers[st->num_of_buffers-1];
|
||||||
|
@ -779,6 +745,8 @@ int caribou_smi_setup_stream(caribou_smi_st* dev,
|
||||||
{
|
{
|
||||||
ZF_LOGE("read stream thread creation failed");
|
ZF_LOGE("read stream thread creation failed");
|
||||||
release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
release_buffer_vec(st->buffers, st->num_of_buffers, st->batch_length);
|
||||||
|
free(st->app_cmplx_vec);
|
||||||
|
free(st->app_meta_vec);
|
||||||
st->buffers = NULL;
|
st->buffers = NULL;
|
||||||
st->active = 0;
|
st->active = 0;
|
||||||
st->running = 0;
|
st->running = 0;
|
||||||
|
@ -869,7 +837,11 @@ int caribou_smi_destroy_stream(caribou_smi_st* dev, int id)
|
||||||
}
|
}
|
||||||
|
|
||||||
release_buffer_vec(dev->streams[id].buffers, dev->streams[id].num_of_buffers, dev->streams[id].batch_length);
|
release_buffer_vec(dev->streams[id].buffers, dev->streams[id].num_of_buffers, dev->streams[id].batch_length);
|
||||||
|
free(dev->streams[id].app_cmplx_vec);
|
||||||
|
free(dev->streams[id].app_meta_vec);
|
||||||
|
|
||||||
|
dev->streams[id].app_cmplx_vec = NULL;
|
||||||
|
dev->streams[id].app_meta_vec = NULL;
|
||||||
dev->streams[id].buffers = NULL;
|
dev->streams[id].buffers = NULL;
|
||||||
dev->streams[id].current_smi_buffer = NULL;
|
dev->streams[id].current_smi_buffer = NULL;
|
||||||
dev->streams[id].current_app_buffer = NULL;
|
dev->streams[id].current_app_buffer = NULL;
|
||||||
|
@ -934,50 +906,7 @@ static void caribou_smi_setup_settings (caribou_smi_st* dev, struct smi_settings
|
||||||
settings->dma_enable = 1;
|
settings->dma_enable = 1;
|
||||||
settings->pack_data = 1;
|
settings->pack_data = 1;
|
||||||
settings->dma_passthrough_enable = 1;
|
settings->dma_passthrough_enable = 1;
|
||||||
|
|
||||||
//settings->dma_read_thresh = 1;
|
|
||||||
//settings->dma_write_thresh = 1;
|
|
||||||
//settings->dma_panic_read_thresh = 1;
|
|
||||||
//settings->dma_panic_write_thresh = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=========================================================================
|
|
||||||
void dump_hex(const void* data, size_t size)
|
|
||||||
{
|
|
||||||
char ascii[17];
|
|
||||||
size_t i, j;
|
|
||||||
ascii[16] = '\0';
|
|
||||||
for (i = 0; i < size; ++i) {
|
|
||||||
printf("%02X ", ((unsigned char*)data)[i]);
|
|
||||||
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~')
|
|
||||||
{
|
|
||||||
ascii[i % 16] = ((unsigned char*)data)[i];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ascii[i % 16] = '.';
|
|
||||||
}
|
|
||||||
if ((i+1) % 8 == 0 || i+1 == size)
|
|
||||||
{
|
|
||||||
printf(" ");
|
|
||||||
if ((i+1) % 16 == 0)
|
|
||||||
{
|
|
||||||
printf("| %s \n", ascii);
|
|
||||||
}
|
|
||||||
else if (i+1 == size)
|
|
||||||
{
|
|
||||||
ascii[(i+1) % 16] = '\0';
|
|
||||||
if ((i+1) % 16 <= 8)
|
|
||||||
{
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
for (j = (i+1) % 16; j < 16; ++j)
|
|
||||||
{
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
printf("| %s \n", ascii);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -41,18 +41,37 @@ typedef enum
|
||||||
caribou_smi_error_read_failed = 0,
|
caribou_smi_error_read_failed = 0,
|
||||||
} caribou_smi_error_en;
|
} caribou_smi_error_en;
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
// associated with CS16 - total 4 bytes / element
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int16_t i; // LSB
|
||||||
|
int16_t q; // MSB
|
||||||
|
} caribou_smi_sample_complex_int16;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t cnt : 2;
|
||||||
|
uint8_t sync1 : 1;
|
||||||
|
uint8_t sync2 : 1;
|
||||||
|
uint8_t res : 4;
|
||||||
|
} caribou_smi_sample_meta;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
#define CARIBOU_SMI_ERROR_STRS { \
|
#define CARIBOU_SMI_ERROR_STRS { \
|
||||||
"reading from SMI source failed", \
|
"reading from SMI source failed", \
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*caribou_smi_data_callback)( void *ctx, // The context of the requesting application
|
typedef void (*caribou_smi_data_callback)( void *ctx, // The context of the requesting application
|
||||||
void *serviced_context, // the context of the session within the app
|
void *serviced_context, // the context of the session within the app
|
||||||
caribou_smi_stream_type_en type, // which type of stream is it? read / write?
|
caribou_smi_stream_type_en type, // which type of stream is it? read / write?
|
||||||
caribou_smi_channel_en ch, // which channel (900 / 2400)
|
caribou_smi_channel_en ch, // which channel (900 / 2400)
|
||||||
uint32_t byte_count, // for "read stream only" - number of read data bytes in buffer
|
size_t num_samples, // for "read stream only" - number of read data bytes in buffer
|
||||||
uint8_t *buffer, // for "read" - data buffer to be analyzed
|
caribou_smi_sample_complex_int16 *cplx_vec, // for "read" - complex vector of samples to be analyzed
|
||||||
// for "write" - the data buffer to be filled with information
|
// for "write" - complex vector of samples to be written into
|
||||||
uint32_t buffer_len_bytes); // the total size of the buffer
|
caribou_smi_sample_meta *metadat_vec, // for "read" - the metadata send by the receiver for each sample
|
||||||
|
// for "write" - the metadata to be written by app for each sample
|
||||||
|
size_t total_length_samples); // The capacity (in terms of samples) in the above vectors
|
||||||
|
|
||||||
typedef void (*caribou_smi_error_callback)( void *ctx,
|
typedef void (*caribou_smi_error_callback)( void *ctx,
|
||||||
caribou_smi_channel_en ch,
|
caribou_smi_channel_en ch,
|
||||||
|
@ -73,6 +92,9 @@ typedef struct
|
||||||
uint8_t *current_smi_buffer; // the buffer that is currently in the SMI DMA
|
uint8_t *current_smi_buffer; // the buffer that is currently in the SMI DMA
|
||||||
uint8_t *current_app_buffer; // the buffer that is currently analyzed / written by the application callback
|
uint8_t *current_app_buffer; // the buffer that is currently analyzed / written by the application callback
|
||||||
|
|
||||||
|
caribou_smi_sample_complex_int16* app_cmplx_vec;
|
||||||
|
caribou_smi_sample_meta* app_meta_vec;
|
||||||
|
|
||||||
int active; // the thread is active
|
int active; // the thread is active
|
||||||
int running; // the stream state - is it running and fetching / pushing information
|
int running; // the stream state - is it running and fetching / pushing information
|
||||||
int stream_id; // the stream id for the application - may be deleted later
|
int stream_id; // the stream id for the application - may be deleted later
|
||||||
|
|
Plik diff jest za duży
Load Diff
|
@ -348,7 +348,7 @@ int cariboulite_init_submodules (cariboulite_st* sys)
|
||||||
|
|
||||||
at86rf215_iq_interface_config_st modem_iq_config = {
|
at86rf215_iq_interface_config_st modem_iq_config = {
|
||||||
.loopback_enable = 0,
|
.loopback_enable = 0,
|
||||||
.drv_strength = at86rf215_iq_drive_current_2ma,
|
.drv_strength = at86rf215_iq_drive_current_4ma,
|
||||||
.common_mode_voltage = at86rf215_iq_common_mode_v_ieee1596_1v2,
|
.common_mode_voltage = at86rf215_iq_common_mode_v_ieee1596_1v2,
|
||||||
.tx_control_with_iq_if = false,
|
.tx_control_with_iq_if = false,
|
||||||
.radio09_mode = at86rf215_iq_if_mode,
|
.radio09_mode = at86rf215_iq_if_mode,
|
||||||
|
|
|
@ -10,15 +10,6 @@
|
||||||
#define IS_POWER_OF_2(x) (!((x) == 0) && !((x) & ((x) - 1)))
|
#define IS_POWER_OF_2(x) (!((x) == 0) && !((x) & ((x) - 1)))
|
||||||
#define MIN(x,y) ((x)>(y)?(y):(x))
|
#define MIN(x,y) ((x)>(y)?(y):(x))
|
||||||
|
|
||||||
uint32_t next_power_of_2 (uint32_t x)
|
|
||||||
{
|
|
||||||
uint32_t power = 1;
|
|
||||||
while(power < x)
|
|
||||||
{
|
|
||||||
power <<= 1;
|
|
||||||
}
|
|
||||||
return power;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class circular_buffer {
|
class circular_buffer {
|
||||||
|
@ -142,6 +133,17 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t next_power_of_2 (uint32_t x)
|
||||||
|
{
|
||||||
|
uint32_t power = 1;
|
||||||
|
while(power < x)
|
||||||
|
{
|
||||||
|
power <<= 1;
|
||||||
|
}
|
||||||
|
return power;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex mutex_;
|
std::mutex mutex_;
|
||||||
std::condition_variable cond_var_;
|
std::condition_variable cond_var_;
|
||||||
|
|
|
@ -30,11 +30,8 @@ enum Cariboulite_Format
|
||||||
CARIBOULITE_FORMAT_FLOAT64 = 3,
|
CARIBOULITE_FORMAT_FLOAT64 = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
//#define BUFFER_SIZE_MS ( 10 )
|
|
||||||
#define NUM_SAMPLEQUEUE_BUFS ( 3 )
|
#define NUM_SAMPLEQUEUE_BUFS ( 3 )
|
||||||
#define NUM_BYTES_PER_CPLX_ELEM ( 4 )
|
#define NUM_BYTES_PER_CPLX_ELEM ( 4 )
|
||||||
//#define GET_MTU_MS(ms) ( 4000*(ms) )
|
|
||||||
//#define GET_MTU_MS_BYTES(ms) ( GET_MTU_MS(ms) * NUM_BYTES_PER_CPLX_ELEM )
|
|
||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
// associated with CS8 - total 2 bytes / element
|
// associated with CS8 - total 2 bytes / element
|
||||||
|
@ -51,13 +48,6 @@ typedef struct
|
||||||
int16_t q :12; // MSB
|
int16_t q :12; // MSB
|
||||||
} sample_complex_int12;
|
} sample_complex_int12;
|
||||||
|
|
||||||
// associated with CS16 - total 4 bytes / element
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int16_t i; // LSB
|
|
||||||
int16_t q; // MSB
|
|
||||||
} sample_complex_int16;
|
|
||||||
|
|
||||||
// associated with CS32 - total 8 bytes / element
|
// associated with CS32 - total 8 bytes / element
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -99,10 +89,10 @@ public:
|
||||||
SampleQueue(int mtu_bytes, int num_buffers);
|
SampleQueue(int mtu_bytes, int num_buffers);
|
||||||
~SampleQueue();
|
~SampleQueue();
|
||||||
int AttachStreamId(int id, int dir, int channel);
|
int AttachStreamId(int id, int dir, int channel);
|
||||||
int Write(uint8_t *buffer, size_t length, uint32_t meta, long timeout_us);
|
int Write(caribou_smi_sample_complex_int16 *buffer, size_t num_samples, uint8_t* meta, long timeout_us);
|
||||||
int Read(uint8_t *buffer, size_t length, uint32_t *meta, long timeout_us);
|
int Read(caribou_smi_sample_complex_int16 *buffer, size_t num_samples, uint8_t *meta, long timeout_us);
|
||||||
|
|
||||||
int ReadSamples(sample_complex_int16* buffer, size_t num_elements, long timeout_us);
|
int ReadSamples(caribou_smi_sample_complex_int16* buffer, size_t num_elements, long timeout_us);
|
||||||
int ReadSamples(sample_complex_float* buffer, size_t num_elements, long timeout_us);
|
int ReadSamples(sample_complex_float* buffer, size_t num_elements, long timeout_us);
|
||||||
int ReadSamples(sample_complex_double* buffer, size_t num_elements, long timeout_us);
|
int ReadSamples(sample_complex_double* buffer, size_t num_elements, long timeout_us);
|
||||||
int ReadSamples(sample_complex_int8* buffer, size_t num_elements, long timeout_us);
|
int ReadSamples(sample_complex_int8* buffer, size_t num_elements, long timeout_us);
|
||||||
|
@ -114,13 +104,13 @@ public:
|
||||||
Cariboulite_Format chosen_format;
|
Cariboulite_Format chosen_format;
|
||||||
int dig_filt;
|
int dig_filt;
|
||||||
private:
|
private:
|
||||||
circular_buffer<sample_complex_int16> *queue;
|
circular_buffer<caribou_smi_sample_complex_int16> *queue;
|
||||||
size_t mtu_size_bytes;
|
size_t mtu_size_bytes;
|
||||||
uint8_t *partial_buffer;
|
uint8_t *partial_buffer;
|
||||||
int partial_buffer_start;
|
int partial_buffer_start;
|
||||||
int partial_buffer_length;
|
int partial_buffer_length;
|
||||||
|
|
||||||
sample_complex_int16 *interm_native_buffer;
|
caribou_smi_sample_complex_int16 *interm_native_buffer;
|
||||||
#define FILT_ORDER 6
|
#define FILT_ORDER 6
|
||||||
#define FILT_ORDER1 8
|
#define FILT_ORDER1 8
|
||||||
Iir::Butterworth::LowPass<FILT_ORDER> filt20_i;
|
Iir::Butterworth::LowPass<FILT_ORDER> filt20_i;
|
||||||
|
|
|
@ -2,34 +2,11 @@
|
||||||
#include <Iir.h>
|
#include <Iir.h>
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============================================
|
|
||||||
void print_iq(uint32_t* array, int len)
|
|
||||||
{
|
|
||||||
//printf("Values I/Q:\n");
|
|
||||||
for (int i=0; i<len; i++)
|
|
||||||
{
|
|
||||||
unsigned int v = array[i];
|
|
||||||
//swap_little_big (&v);
|
|
||||||
|
|
||||||
int16_t q_val = (v>> 1) & (0x1FFF);
|
|
||||||
int16_t i_val = (v>>17) & (0x1FFF);
|
|
||||||
if (q_val >= 0x1000) q_val-=0x2000;
|
|
||||||
if (i_val >= 0x1000) i_val-=0x2000;
|
|
||||||
float fi = i_val, fq = q_val;
|
|
||||||
float mod = sqrt(fi*fi + fq*fq);
|
|
||||||
float arg = atan2(fq, fi);
|
|
||||||
printf("(%d, %d), ", i_val, q_val);
|
|
||||||
if ((i % 32) == 0) printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//=================================================================
|
//=================================================================
|
||||||
SampleQueue::SampleQueue(int mtu_bytes, int num_buffers)
|
SampleQueue::SampleQueue(int mtu_bytes, int num_buffers)
|
||||||
{
|
{
|
||||||
SoapySDR_logf(SOAPY_SDR_INFO, "Creating SampleQueue MTU: %d bytes, NumBuffers: %d", mtu_bytes, num_buffers);
|
SoapySDR_logf(SOAPY_SDR_INFO, "Creating SampleQueue MTU: %d bytes, NumBuffers: %d", mtu_bytes, num_buffers);
|
||||||
queue = new circular_buffer(mtu_bytes / 4 * num_buffers)
|
queue = new circular_buffer<caribou_smi_sample_complex_int16>(mtu_bytes / 4 * num_buffers*10);
|
||||||
mtu_size_bytes = mtu_bytes;
|
mtu_size_bytes = mtu_bytes;
|
||||||
stream_id = -1;
|
stream_id = -1;
|
||||||
stream_dir = -1;
|
stream_dir = -1;
|
||||||
|
@ -42,7 +19,7 @@ SampleQueue::SampleQueue(int mtu_bytes, int num_buffers)
|
||||||
|
|
||||||
// a buffer for conversion betwen native and emulated formats
|
// a buffer for conversion betwen native and emulated formats
|
||||||
// the maximal size is the 2*(mtu_size in bytes)
|
// the maximal size is the 2*(mtu_size in bytes)
|
||||||
interm_native_buffer = new sample_complex_int16[2*mtu_size_bytes];
|
interm_native_buffer = new caribou_smi_sample_complex_int16[2*mtu_size_bytes];
|
||||||
is_cw = 0;
|
is_cw = 0;
|
||||||
|
|
||||||
filt20_i.setup(4e6, 20e3/2);
|
filt20_i.setup(4e6, 20e3/2);
|
||||||
|
@ -61,9 +38,6 @@ SampleQueue::SampleQueue(int mtu_bytes, int num_buffers)
|
||||||
//=================================================================
|
//=================================================================
|
||||||
SampleQueue::~SampleQueue()
|
SampleQueue::~SampleQueue()
|
||||||
{
|
{
|
||||||
//printf("~SampleQueue streamID: %d, dir: %d, channel: %d\n", stream_id, stream_dir, stream_channel);
|
|
||||||
//SoapySDR_logf(SOAPY_SDR_INFO, "~SampleQueue streamID: %d, dir: %d, channel: %d", stream_id, stream_dir, stream_channel);
|
|
||||||
|
|
||||||
stream_id = -1;
|
stream_id = -1;
|
||||||
stream_dir = -1;
|
stream_dir = -1;
|
||||||
stream_channel = -1;
|
stream_channel = -1;
|
||||||
|
@ -88,131 +62,35 @@ int SampleQueue::AttachStreamId(int id, int dir, int channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
//=================================================================
|
//=================================================================
|
||||||
int SampleQueue::Write(sample_complex_int16 *buffer, size_t num_samples, uint8_t* meta, long timeout_us)
|
int SampleQueue::Write(caribou_smi_sample_complex_int16 *buffer, size_t num_samples, uint8_t* meta, long timeout_us)
|
||||||
{
|
{
|
||||||
return queue->put(buffer, elements)
|
return queue->put(buffer, num_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=================================================================
|
//=================================================================
|
||||||
int SampleQueue::Read(uint8_t *buffer, size_t length, uint32_t *meta, long timeout_us)
|
int SampleQueue::Read(caribou_smi_sample_complex_int16 *buffer, size_t num_samples, uint8_t *meta, long timeout_us)
|
||||||
{
|
{
|
||||||
tsqueue_item_st* item_ptr = NULL;
|
return queue->get(buffer, num_samples);
|
||||||
int left_to_read = length;
|
|
||||||
int read_so_far = 0;
|
|
||||||
int chunk = 0;
|
|
||||||
|
|
||||||
// first read out from partial buffer
|
|
||||||
int amount_to_read_from_partial = (left_to_read <= partial_buffer_length) ?
|
|
||||||
left_to_read : partial_buffer_length;
|
|
||||||
memcpy (buffer, partial_buffer + partial_buffer_start, amount_to_read_from_partial);
|
|
||||||
left_to_read -= amount_to_read_from_partial;
|
|
||||||
partial_buffer_length -= amount_to_read_from_partial;
|
|
||||||
partial_buffer_start += amount_to_read_from_partial;
|
|
||||||
read_so_far += amount_to_read_from_partial;
|
|
||||||
|
|
||||||
// read from the queue
|
|
||||||
while (left_to_read)
|
|
||||||
{
|
|
||||||
int res = tsqueue_pop_item(&queue, &item_ptr, timeout_us);
|
|
||||||
switch (res)
|
|
||||||
{
|
|
||||||
case TSQUEUE_NOT_INITIALIZED:
|
|
||||||
case TSQUEUE_SEM_FAILED:
|
|
||||||
{
|
|
||||||
SoapySDR_logf(SOAPY_SDR_ERROR, "popping buffer %d failed", chunk);
|
|
||||||
return -1;
|
|
||||||
} break;
|
|
||||||
case TSQUEUE_TIMEOUT:
|
|
||||||
case TSQUEUE_FAILED_EMPTY: return read_so_far; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
if (meta) *meta = item_ptr->metadata;
|
|
||||||
|
|
||||||
// if we need more or exactly the mtu size
|
|
||||||
if (left_to_read >= item_ptr->length)
|
|
||||||
{
|
|
||||||
memcpy(&buffer[read_so_far], item_ptr->data, item_ptr->length);
|
|
||||||
left_to_read -= item_ptr->length;
|
|
||||||
read_so_far += item_ptr->length;
|
|
||||||
}
|
|
||||||
// if we need less than the mtu size - store the residue for next time
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// copy out only the amount that is needed
|
|
||||||
memcpy(&buffer[read_so_far], item_ptr->data, left_to_read);
|
|
||||||
|
|
||||||
// we are left with "item_ptr->length - left_to_read" bytes
|
|
||||||
// which will be stored for future requests
|
|
||||||
|
|
||||||
// store the residue in the partial buffer - for the next time
|
|
||||||
partial_buffer_length = item_ptr->length - left_to_read;
|
|
||||||
partial_buffer_start = (int)mtu_size_bytes - partial_buffer_length;
|
|
||||||
memcpy (partial_buffer + partial_buffer_start,
|
|
||||||
item_ptr->data + left_to_read,
|
|
||||||
partial_buffer_length);
|
|
||||||
|
|
||||||
read_so_far += left_to_read;
|
|
||||||
left_to_read = 0;
|
|
||||||
}
|
|
||||||
chunk ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return read_so_far;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//=================================================================
|
//=================================================================
|
||||||
int SampleQueue::ReadSamples(sample_complex_int16* buffer, size_t num_elements, long timeout_us)
|
int SampleQueue::ReadSamples(caribou_smi_sample_complex_int16* buffer, size_t num_elements, long timeout_us)
|
||||||
{
|
{
|
||||||
static int once = 100;
|
static int once = 100;
|
||||||
static uint16_t last_q = 0;
|
static uint16_t last_q = 0;
|
||||||
// this is the native method
|
|
||||||
int tot_length = num_elements * sizeof(sample_complex_int16);
|
int res = Read(buffer, num_elements, NULL, timeout_us);
|
||||||
int res = Read((uint8_t *)buffer, tot_length, NULL, timeout_us);
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
{
|
{
|
||||||
// todo!!
|
// todo!!
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tot_read_elements = res / sizeof(sample_complex_int16);
|
int tot_read_elements = res;
|
||||||
|
|
||||||
// shift q
|
|
||||||
//buffer[0].q = last_q;
|
|
||||||
/*for (int i = 1; i < tot_read_elements; i++)
|
|
||||||
{
|
|
||||||
buffer[i-1].q = buffer[i].q;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*for (int i = 1; i < tot_read_elements; i+=2)
|
|
||||||
{
|
|
||||||
short t = buffer[i].i;
|
|
||||||
buffer[i].i = buffer[i+1].i;
|
|
||||||
buffer[i+1].i = t;
|
|
||||||
t = buffer[i].q;
|
|
||||||
buffer[i].q = buffer[i+1].q;
|
|
||||||
buffer[i+1].q = t;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*for (int i = tot_read_elements-1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
buffer[i].q = buffer[i-1].q;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
for (int i = 0; i < tot_read_elements; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
buffer[i].i >>= 1;
|
|
||||||
buffer[i].q >>= 1;
|
|
||||||
|
|
||||||
buffer[i].i = buffer[i].i & 0x1FFF;
|
|
||||||
buffer[i].q = buffer[i].q & 0x1FFF;
|
|
||||||
|
|
||||||
if (buffer[i].i >= (int16_t)0x1000) buffer[i].i -= (int16_t)0x2000;
|
|
||||||
if (buffer[i].q >= (int16_t)0x1000) buffer[i].q -= (int16_t)0x2000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tot_read_elements;
|
return tot_read_elements;
|
||||||
|
|
||||||
|
// digital filters - TBD
|
||||||
if (dig_filt == 0)
|
if (dig_filt == 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < res; i++)
|
for (int i = 0; i < res; i++)
|
||||||
|
@ -260,7 +138,7 @@ int SampleQueue::ReadSamples(sample_complex_int16* buffer, size_t num_elements,
|
||||||
//=================================================================
|
//=================================================================
|
||||||
int SampleQueue::ReadSamples(sample_complex_float* buffer, size_t num_elements, long timeout_us)
|
int SampleQueue::ReadSamples(sample_complex_float* buffer, size_t num_elements, long timeout_us)
|
||||||
{
|
{
|
||||||
uint32_t max_native_samples = 2*(mtu_size_bytes / sizeof(sample_complex_int16));
|
uint32_t max_native_samples = 2*(mtu_size_bytes / sizeof(caribou_smi_sample_complex_int16));
|
||||||
|
|
||||||
// do not allow to store more than is possible in the intermediate buffer
|
// do not allow to store more than is possible in the intermediate buffer
|
||||||
if (num_elements > max_native_samples)
|
if (num_elements > max_native_samples)
|
||||||
|
@ -332,7 +210,7 @@ int SampleQueue::ReadSamples(sample_complex_float* buffer, size_t num_elements,
|
||||||
//=================================================================
|
//=================================================================
|
||||||
int SampleQueue::ReadSamples(sample_complex_double* buffer, size_t num_elements, long timeout_us)
|
int SampleQueue::ReadSamples(sample_complex_double* buffer, size_t num_elements, long timeout_us)
|
||||||
{
|
{
|
||||||
uint32_t max_native_samples = 2*(mtu_size_bytes / sizeof(sample_complex_int16));
|
uint32_t max_native_samples = 2*(mtu_size_bytes / sizeof(caribou_smi_sample_complex_int16));
|
||||||
|
|
||||||
// do not allow to store more than is possible in the intermediate buffer
|
// do not allow to store more than is possible in the intermediate buffer
|
||||||
if (num_elements > max_native_samples)
|
if (num_elements > max_native_samples)
|
||||||
|
@ -362,7 +240,7 @@ int SampleQueue::ReadSamples(sample_complex_double* buffer, size_t num_elements,
|
||||||
//=================================================================
|
//=================================================================
|
||||||
int SampleQueue::ReadSamples(sample_complex_int8* buffer, size_t num_elements, long timeout_us)
|
int SampleQueue::ReadSamples(sample_complex_int8* buffer, size_t num_elements, long timeout_us)
|
||||||
{
|
{
|
||||||
uint32_t max_native_samples = 2*(mtu_size_bytes / sizeof(sample_complex_int16));
|
uint32_t max_native_samples = 2*(mtu_size_bytes / sizeof(caribou_smi_sample_complex_int16));
|
||||||
|
|
||||||
// do not allow to store more than is possible in the intermediate buffer
|
// do not allow to store more than is possible in the intermediate buffer
|
||||||
if (num_elements > max_native_samples)
|
if (num_elements > max_native_samples)
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
#include "Cariboulite.hpp"
|
#include "Cariboulite.hpp"
|
||||||
#include "cariboulite_config/cariboulite_config_default.h"
|
#include "cariboulite_config/cariboulite_config_default.h"
|
||||||
|
|
||||||
|
|
||||||
//=================================================================
|
//=================================================================
|
||||||
static void caribou_stream_data_event( void *ctx,
|
static void caribou_stream_data_event( void *ctx,
|
||||||
void *service_context,
|
void *service_context,
|
||||||
caribou_smi_stream_type_en type,
|
caribou_smi_stream_type_en type,
|
||||||
caribou_smi_channel_en ch,
|
caribou_smi_channel_en ch,
|
||||||
uint32_t byte_count,
|
size_t sample_count,
|
||||||
uint8_t *buffer,
|
caribou_smi_sample_complex_int16 *cmplx_vec,
|
||||||
uint32_t buffer_len_bytes)
|
caribou_smi_sample_meta *meta_vec,
|
||||||
|
size_t buffers_capacity_samples)
|
||||||
{
|
{
|
||||||
cariboulite_st* sys = (cariboulite_st*)ctx;
|
cariboulite_st* sys = (cariboulite_st*)ctx;
|
||||||
Cariboulite *obj = (Cariboulite*)service_context;
|
Cariboulite *obj = (Cariboulite*)service_context;
|
||||||
|
@ -23,7 +23,7 @@ static void caribou_stream_data_event( void *ctx,
|
||||||
case caribou_smi_stream_type_read:
|
case caribou_smi_stream_type_read:
|
||||||
{
|
{
|
||||||
int sample_queue_index = CARIBOU_SMI_GET_STREAM_ID(type, ch);
|
int sample_queue_index = CARIBOU_SMI_GET_STREAM_ID(type, ch);
|
||||||
obj->sample_queues[sample_queue_index]->Write(buffer, buffer_len_bytes, 0, 10000L);
|
obj->sample_queues[sample_queue_index]->Write(cmplx_vec, sample_count, 0, 10000L);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -38,16 +38,16 @@ static void caribou_stream_data_event( void *ctx,
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
case caribou_smi_stream_start:
|
case caribou_smi_stream_start:
|
||||||
{
|
{
|
||||||
SoapySDR_logf(SOAPY_SDR_DEBUG, "start event: stream channel %d, batch length: %d bytes",
|
SoapySDR_logf(SOAPY_SDR_DEBUG, "start event: stream channel %d, batch length: %d samples",
|
||||||
ch, buffer_len_bytes);
|
ch, buffers_capacity_samples);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//-------------------------------------------------------
|
//-------------------------------------------------------
|
||||||
case caribou_smi_stream_end:
|
case caribou_smi_stream_end:
|
||||||
{
|
{
|
||||||
SoapySDR_logf(SOAPY_SDR_DEBUG, "end event: stream channel %d, batch length: %d bytes",
|
SoapySDR_logf(SOAPY_SDR_DEBUG, "end event: stream channel %d, batch length: %d sample",
|
||||||
ch, buffer_len_bytes);
|
ch, buffers_capacity_samples);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ void Cariboulite::closeStream(SoapySDR::Stream *stream)
|
||||||
size_t Cariboulite::getStreamMTU(SoapySDR::Stream *stream) const
|
size_t Cariboulite::getStreamMTU(SoapySDR::Stream *stream) const
|
||||||
{
|
{
|
||||||
//printf("getStreamMTU\n");
|
//printf("getStreamMTU\n");
|
||||||
return 1024 * 1024 / 2 / 4; // # milliseconds of buffer
|
return 1024 * 1024 / 2 / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
//========================================================
|
//========================================================
|
||||||
|
@ -399,7 +399,7 @@ int Cariboulite::readStream(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CARIBOULITE_FORMAT_INT16:
|
case CARIBOULITE_FORMAT_INT16:
|
||||||
res = sample_queues[stream_id]->ReadSamples((sample_complex_int16*)buffs[0], numElems, timeoutUs);
|
res = sample_queues[stream_id]->ReadSamples((caribou_smi_sample_complex_int16*)buffs[0], numElems, timeoutUs);
|
||||||
break;
|
break;
|
||||||
case CARIBOULITE_FORMAT_INT8:
|
case CARIBOULITE_FORMAT_INT8:
|
||||||
res = sample_queues[stream_id]->ReadSamples((sample_complex_int8*)buffs[0], numElems, timeoutUs);
|
res = sample_queues[stream_id]->ReadSamples((sample_complex_int8*)buffs[0], numElems, timeoutUs);
|
||||||
|
|
Ładowanie…
Reference in New Issue