jgaeddert / liquid-dsp

digital signal processing library for software-defined radios
http://liquidsdr.org
MIT License
1.9k stars 443 forks source link

Intermittent Correct output with SoapySDR (SoapyPlutoSDR) #381

Open Mas313 opened 2 months ago

Mas313 commented 2 months ago

Hi, Although the examples run fine but i am getting intermitent results when i integrate liquiddsp with SoapyplutoSDR for a real world application. The output is received correctly 3 out of 100 times. May be i am doing something wrong. The code below explains tx and rx side logic on a plutoSDRs. Since pluto is full duplex so Rx results can be seen. On th rx side consumer thread is shown where rxsamples is a shared buffer and is verified for syncrhonnized access. Running only rx side code on other pluto also gives intermittent success which is very low with FEC used

```
    unsigned int k           = 8;       // samples/symbol
    unsigned int m           = 7;       // filter delay (symbols)
    float        BT          = 0.4f;    // filter bandwidth-time product

    crc_scheme   check       = LIQUID_CRC_32;// LIQUID_CRC_32
    fec_scheme   fec0        = LIQUID_FEC_HAMMING128; 
    fec_scheme   fec1        = LIQUID_FEC_GOLAY2412;
// allocate memory for payload and initialize
unsigned char header[8] = {0,1,2,3,4,5,6,7};
//memset(payload, 0x00, payload_len);
gmskframegen fg = gmskframegen_create_set(k, m, BT);
int pcount=0;

while(run ) 
{
unsigned char payload[]="ABCDEFGHIJ-12345678" 
payload_len=strlen(payload);
//create frame generator and assemble
gmskframegen_assemble(fg, header, payload, payload_len, check, fec0, fec1);

    // allocate buffer for storing entire frame
    unsigned int num_samples = gmskframegen_getframelen(fg) + 800;

    // Create a buffer for filtered samples
float complex txsamples[num_samples];

    // generate frame in one shot with sample offset
    gmskframegen_write(fg, txsamples, num_samples);

int flags=0; //flags set by receive operation
    long long timeNs=1000000; //timestamp for receive buffer

float complex *ptr;    
int j=num_samples;
int count=0;
ptr=txsamples;

while(j > 0){
    void *buffsTx[]={ptr}; //array of buffers
    int ret= SoapySDRDevice_writeStream(sdr, txStream,buffsTx,j,&flags,timeNs,1000000); //100000 

if (ret==SOAPY_SDR_TIMEOUT){
            printf("SOAPY_SDR_TIMEOUT\n");
        //continue;
} 
else if( ret==SOAPY_SDR_STREAM_ERROR ){
    printf("SOAPY_SDR_STREAM_ERROR\n");
//continue;
}
else if( ret==SOAPY_SDR_CORRUPTION){
    printf("SOAPY_SDR_CORRUPTION\n");
//continue;
}
else if( ret==SOAPY_SDR_OVERFLOW){
printf("SOAPY_SDR_OVERFLOW\n");
//continue;
}
else if( ret==SOAPY_SDR_NOT_SUPPORTED){
printf("SOAPY_SDR_NOT_SUPPORTED\n");
//continue;
}
else if( ret== SOAPY_SDR_TIME_ERROR){
    printf(" SOAPY_SDR_TIME_ERROR\n");
//continue;
}
else if( ret== SOAPY_SDR_UNDERFLOW){
    printf(" SOAPY_SDR_UNDERFLOW\n");
//continue;
}
else if (ret>0)
{                       
printf("Sucesfully Sent ret=%d \n",ret);    
}           
j -= ret;
ptr += ret;     
}
usleep(1);

} gmskframegen_destroy(fg);


Rx side Code, running in a thread

gmskframesync fs = gmskframesync_create_set(k, m, BT, callback1, NULL);

liquid_float_complex rxsamples[8192];
// design filter from prototype and scale to bandwidth

    while(run)
{

        pthread_mutex_lock(&mutex);

    while(!data_available){
        pthread_cond_wait(&cond_cons,&mutex);
    }
    consumers_done++;
    rx_count++;

           if(consumers_done==NUM_CONSUMERS){
    //printf("Consumer---Resetting id=%d rx_count=%d\n",pthread_self(),rx_count);
    data_available=0;
    consumers_done=0;
    pthread_cond_signal(&cond_prod);
    }
    pthread_mutex_unlock(&mutex);
    //convert to format

    gmskframesync_execute(fs, rxsamples, ret);
        usleep(1);  
    } //while   
    gmskframesync_destroy(fs);