Teensy Convolution SDR (Software Defined Radio)

Hello together,

here is a small update on the status of my MSi001 Teensy convolution project.
After doing some additional shielding of the board and putting everything together in the metal box and as planned supplyng it from Li ion battery, I succeeded to drop the noise floor slightly lower than before (see the table below). But the main task was to check the actual dynamic range with current hardware (SGTL5000 - VDDA=3.3V claims SNR-90dB).
Basically used the algorithm proposed from Frank.
......
Concerning the "bit resolution", I personally think it would be better to measure the "dynamic range" of the whole system:
* use 50 Ohm resistor instead of an antenna
* "measure" the noise level in 500Hz bandwidth
* insert a signal of defined (high) signal level into the antenna input
* measure the largest signal level without compression / desensibilization in 500Hz bandwidth
* and the difference between the two measurements is the dynamic range of the whole SDR system
* if you can achieve 16 bit == 96dB, your system will be high end quality, I think :)
.........

The settings are also included in the picture

Dynamic_Range_Measurement.png
The dynamic range that I succeeded to measure is roughly around 82dB, equivalent of around 14 bit resolution.

Second topic is more for fun :)
Last days I got a bit more time and I add some kind of "Menu Assistant"
20200724_213256_T.jpg20200724_213340_T.jpg
Now it is possible with long press of the encoder to call the "Menu Assistant" and it is possible to scroll up and down, change the selected position and as well is indicated small block diagram to to give you hint what you change at the moment.
As an advantage it is possible to scroll with the encoder directly (much faster) and also 7 positions of the menu are visible at a time.

The actual code lies here:
https://www.dropbox.com/s/64i77appz8sz1lc/Teensy_Convolution_SDR_Msi001_v3_5_2020_07_24.rar?dl=0
 
Hi Bill, did you have time to measure the dynamic range of you one? I am curious to see how the TI ADC is performing.
 
Hi Bill, did you have time to measure the dynamic range of you one? I am curious to see how the TI ADC is performing.

I didn't measure it yet. I need to get some more attenuators. I used to have a whole bunch of them but now I only have a few.
 
Fantastic developments! I am really impressed!
@tisho: the menu looks excellent! I would really like to include it into the main code. Is it possible that you submit a pull request to my github? it would be very laborious to take the code from your repo and merge it by hand . . .
Also the figures look very good! We should not expect miracles from a 3$-chip ;-). But the figures look very satisfying and could possibly be improved by adding an attenuator at the antenna input or simply by switching off the preamp
@Bill: your MATLAB experiments look very good! I am a total newbie to MATLAB, so I am very impressed. Also, I am not so good in the DSP-associated math, my approach to the DSP-subject is more like thinking in graphical blocks :).
we had some discussion here in the forum on the minimum phase FIR filters and there is also a nice video of a talk by Warren Pratt during the HAM RADIO fair in Friedrichshafen in 2018, which is very informative.

I will not have the opportunity to do much on the subject in the next three weeks, so I will remain silent and come back to the forum in a few weeks.
 
...
I agree that the 74LVC4066 is a great chip. According to the data sheet, the typical t-on time is 2.5 ns and the t-off time is 3.4 ns which is very fast.

Here is what I have been thinking about when I should have been sleeping... In this mixer circuit, if I have my receiver set to my maximum (non-multiplied) frequency of 50 MHz, the clock period is 20 ns (1/50 MHz). So the quadrature switches are each on for 1/4 of each 20 ns period. This means that each switch is on for 5 ns and off for 15 ns (I'm ignoring the second set of four switches but they are doing exactly the same thing). But when I consider the delays in the 74LVC4066, my switches turn on faster than they it turn off (typical of FETs due to their gate capacitance). Say we start a timer when the first switch turns on at t=0 ns. The first switch should turn off at t=5 ns and at the same time, the second switch should turn on. But the first switch actually turns on at t=2.5 ns and turns off at t=8.4 ns (5 ns + 3.4 ns). The second switch turns on at 7.5 ns (5 ns + 2.5 ns). So during the time between 7.5 ns and 8.4 ns both switches are on! This happens four times each period so we have two switches on for a total time of 0.9*4 ns = 3.6 ns during the period. This is 18% of the period.
...

Your calculation is only right for the 3253 with the internal 1:4 decoder. A QSD with a 4066 switch IC each switch of the four switches are a half RF period on and of!
 
Hi Frank,
Would like to start with that I am a newbie with the GitHib.
I made a "pull request" but have a feeling it didn't work as expected (somehow it is showing to many changes in the main "ino" file, but the file it is correct). Nonetheless when you have time you can take a look, you can see that the whole "Menu Assistant" it is in a separate "ino" file so the merge will be not that hard.
Meanwhile I will read a bit more in the GitHub documentation to see if I really did everything correct.
 
Hi Frank,
Would like to start with that I am a newbie with the GitHib.
I made a "pull request" but have a feeling it didn't work as expected (somehow it is showing to many changes in the main "ino" file, but the file it is correct). Nonetheless when you have time you can take a look, you can see that the whole "Menu Assistant" it is in a separate "ino" file so the merge will be not that hard.
Meanwhile I will read a bit more in the GitHub documentation to see if I really did everything correct.
Thanks a Lot! Will Take a Look in August, sorry, that its Not possible earlier!
 
Hello,

I have seen that in addition to the menus, you have incorporated the AFC into the original teensy msi001 support, good work.

My two cents: It would be interesting if Frank and the others think about adopting a reference hardware for the github master, to facilitate code maintenance in the near future.

Greetings, Esteban EA8DGL.


Hello together,

here is a small update on the status of my MSi001 Teensy convolution project.
After doing some additional shielding of the board and putting everything together in the metal box and as planned supplyng it from Li ion battery, I succeeded to drop the noise floor slightly lower than before (see the table below). But the main task was to check the actual dynamic range with current hardware (SGTL5000 - VDDA=3.3V claims SNR-90dB).
Basically used the algorithm proposed from Frank.


The settings are also included in the picture

View attachment 21112
The dynamic range that I succeeded to measure is roughly around 82dB, equivalent of around 14 bit resolution.

Second topic is more for fun :)
Last days I got a bit more time and I add some kind of "Menu Assistant"
View attachment 21113View attachment 21114
Now it is possible with long press of the encoder to call the "Menu Assistant" and it is possible to scroll up and down, change the selected position and as well is indicated small block diagram to to give you hint what you change at the moment.
As an advantage it is possible to scroll with the encoder directly (much faster) and also 7 positions of the menu are visible at a time.

The actual code lies here:
https://www.dropbox.com/s/64i77appz8sz1lc/Teensy_Convolution_SDR_Msi001_v3_5_2020_07_24.rar?dl=0
 
@Esteban, @tisho
Thanks again, to you, Esteban and your colleague EA7GIB for your kindness to send me a Msi001 board for integration into the Convolution SDR software!
I am working hard to get it working properly and optimize.

There are several open questions I would like to ask you [I only have a basic understanding of the Msi001 chip taken from the datasheet, so some things may be obvious for you, but not clear to me ;-)]

1.) datasheet p. 9 says: "IF bandwidths of 200kHz are recommended for use at Fif = 450kHz only. As far as I understand, the Msi001 runs in "zero-IF-mode" and 200kHz bandwidth. If so, datasheet p. 10 says, the smallest bandwidth is 1.536MHz and reg0 [16:14] should be set to 011. Is that true? And how could I alter the Msi code to account for this?

2.) If no. 1.) is correct, we have a 1.536Mhz signal for the I & Q inputs of the PCM1808 ADC, which runs at a sample rate of 96kHz to max. 256kHz. This leads to considerable aliasing (and could possibly explain the many birdies I see)! So we need two good anti-alias-filters for the I & Q inputs. Is that correct?

3.) the crystal frequency setting in the code is commented out. The reg0 is set by this
Code:
reg0 |= 0x02 << 17; // problema con el XTAL no sé por qué
However, this is only correct for a crystal with 24Mhz, not for the crystal in my hardware, which has a 22MHz crystal. However, if I use:
Code:
reg0 |= 0x01 << 17;
the Msi001 seems non-functional. Do you experience the same?

4.) datasheet p. 16, it says: "Important note: Register 5 bits 19 and 21 need to be set high for correct operation of the part." [in the context of AFC]. However, I could not find this in the Msi code. Did I overlook this, or is it not needed?

5.) is there a reason, why the whole Msi001 initialization routine is performed every time the frequency is changed? This leads to annoying spectrum display distortion (the display jumps on every tuning step) and a considerable latency. In my understanding, only reg3 (and sometimes reg2) would have to be updated.

Sorry for so many questions, I am a beginner in understanding these highly integrated circuits with synthezisers, mixers etc., so I probably misunderstood many things. My main goal is to understand that chip and make optimal use of it ;-).

Best 73s,

Frank DD4WH

P.S.: and could you explain, what this is for?
Code:
  /* kernel driver adjusts to changing frequencies  */

  mirisdr_write_reg( 0xf380);
  mirisdr_write_reg( 0x6280);
  mirisdr_write_reg( switch_plan.band_select_word);

  mirisdr_write_reg( 0x0e); //OK
  mirisdr_write_reg( 0x03); //OK
 
Last edited:
@Esteban, @tisho
Thanks again, to you, Esteban and your colleague EA7GIB for your kindness to send me a Msi001 board for integration into the Convolution SDR software!
I am working hard to get it working properly and optimize.

Thank you for Convolution SDR and it would be great if we can workout the issues and have a wide coverage receiver. First of all, let me say that the SDRPLAY API is closed source so this port is based on linux reverse engineered driver:

https://github.com/f4exb/libmirisdr-4

AFAIK, all SDR software use the closed source so we don't have source of functions, only low level driver functions.

There are several open questions I would like to ask you [I only have a basic understanding of the Msi001 chip taken from the datasheet, so some things may be obvious for you, but not clear to me ;-)]

1.) datasheet p. 9 says: "IF bandwidths of 200kHz are recommended for use at Fif = 450kHz only. As far as I understand, the Msi001 runs in "zero-IF-mode" and 200kHz bandwidth. If so, datasheet p. 10 says, the smallest bandwidth is 1.536MHz and reg0 [16:14] should be set to 011. Is that true? And how could I alter the Msi code to account for this?

setup() in msi001.ino uses the struct variable p with those parameters:

p.if_freq = MIRISDR_IF_ZERO;
p.bandwidth = MIRISDR_BW_200KHZ;

I look at msi001 IF with an srdplay RSP1A and BW seems correct.

2.) If no. 1.) is correct, we have a 1.536Mhz signal for the I & Q inputs of the PCM1808 ADC, which runs at a sample rate of 96kHz to max. 256kHz. This leads to considerable aliasing (and could possibly explain the many birdies I see)! So we need two good anti-alias-filters for the I & Q inputs. Is that correct?

Perhaps by installing audio transformers we can reduce the bandwidth that appears on the ADC and reduce aliasing.

3.) the crystal frequency setting in the code is commented out. The reg0 is set by this
Code:
reg0 |= 0x02 << 17; // problema con el XTAL no sé por qué
However, this is only correct for a crystal with 24Mhz, not for the crystal in my hardware, which has a 22MHz crystal. However, if I use:
Code:
reg0 |= 0x01 << 17;
the Msi001 seems non-functional. Do you experience the same?

Yes, this is a dirty hack... The linux driver follows the datasheet but, in my port, for the frequency of 22 Mhz, programming the clock as it says the datasheet does not work.

4.) datasheet p. 16, it says: "Important note: Register 5 bits 19 and 21 need to be set high for correct operation of the part." [in the context of AFC]. However, I could not find this in the Msi code. Did I overlook this, or is it not needed?

Tisho added the AFC functionality in the code and maybe he can explain it better.

5.) is there a reason, why the whole Msi001 initialization routine is performed every time the frequency is changed? This leads to annoying spectrum display distortion (the display jumps on every tuning step) and a considerable latency. In my understanding, only reg3 (and sometimes reg2) would have to be updated.

Good find. Besides this, with both no AFC and AFC, there is an obvious frequency fine tuning issue that needs to be investigated.

Sorry for so many questions, I am a beginner in understanding these highly integrated circuits with synthezisers, mixers etc., so I probably misunderstood many things. My main goal is to understand that chip and make optimal use of it ;-).
Of course I'm not a msi001 nor sdr guru, original driver is incomplete and untested and I've introduced more bugs in the teensy version for sure.

P.S.: and could you explain, what this is for?
Code:
  /* kernel driver adjusts to changing frequencies  */

  mirisdr_write_reg( 0xf380);
  mirisdr_write_reg( 0x6280);
  mirisdr_write_reg( switch_plan.band_select_word);

  mirisdr_write_reg( 0x0e); //OK
  mirisdr_write_reg( 0x03); //OK

0xf380 and 0x6280 seems related to reg1 (registers are sent lsb to msb, so 0x8 is 1000 = reg 1 as original linux driver reg write funtion does:

mirisdr_write_reg(p, 0x08, 0x00f380); /* kernel driver */

int mirisdr_write_reg (mirisdr_dev_t *p, uint8_t reg, uint32_t val) {
uint16_t value = (val & 0xff) << 8 | reg;
uint16_t index = (val >> 8) & 0xffff;

libusb_control_transfer(p->dh, 0x42, 0x41, value, index, NULL, 0, CTRL_TIMEOUT);

}

Seems we have a serious bug here, as we can't send 0xf380 using the teensy write reg version as it will write to register 0x00 instead to the correct one, the gain register 0x01.

We have to shift left 4 bits and then OR 1 before sending to the msi001 ... :confused:

Regards,

Esteban EA8DGL.
 
Minor changes to the Convolution

It is the first time that I am writing on this forum and I want to congratulate DD4WH for the excellent project that worked for me immediately using softrock hardware, Teensy 4.1, ILI934 Display, PCM1808, PCM5102A, Si5351. I describe some changes I made to the software to adapt it to my needs as a radio amateur (IK6BLO) in order to combine a traditional analog transmitter with balanced modulator and crystal filter to the Convolution.
I assigned const uint8_t pinE = 37, so as to make pin 37 in USB Hight to drive an SSB relay driven by a BS170 FET which serves for the carrier's quartz generator.

void setup_mode(int MO)
{
// bands[current_band].mode
// USB -> LSB -> AM -> SAM -> SAM Stereo -> IQ -> WFM ->
int temp;

if (old_demod_mode != -99) // first time when radio is switched on and when changing bands
{digitalWrite (pinE, HIGH);// USB
if (MO == DEMOD_LSB) // switch from USB to LSB
{digitalWrite (pinE, LOW);// USB
temp = bands[current_band].FHiCut;
bands[current_band].FHiCut = - bands[current_band].FLoCut;
bands[current_band].FLoCut = - temp;
}

After declaring the ANTX variable
unsigned long long ANTX=0;

I activated CLK0 of Si5351 to get the receiving frequency added to a constant (different USB-LSB) equal to the frequency of the SSB generator, in my case 9 Mhz
void setfreq () {
// Changes for Bobs Octave Filters: 18 March 2018 W7PUA <<<<<<
// http://www.janbob.com/electron/FilterBP1/FiltBP1.html


// NEVER USE AUDIONOINTERRUPTS HERE: that introduces annoying clicking noise with every frequency change
// hilfsf = (bands[current_band].freq + IF_FREQ) * 10000000 * MASTER_CLK_MULT * SI5351_FREQ_MULT;
hilfsf = (bands[current_band].freq + IF_FREQ * SI5351_FREQ_MULT) * 1000000000 * MASTER_CLK_MULT; // SI5351_FREQ_MULT is 100ULL;
hilfsf = hilfsf / calibration_factor;
ANTX=hilfsf / 4;//DIVIDO LA FREQUENZA PER 4

if (digitalRead(pinE) == LOW) {
si5351.set_freq(ANTX + 897270000 , SI5351_CLK0);
} else {
si5351.set_freq(ANTX + 897580000 , SI5351_CLK0);
}

si5351.set_freq(hilfsf, Si_5351_clock);
IMAG2.jpg
 
Hello Frank,
I would like to say that the datasheet is kind of funny, and not really understandable on many points

@Esteban, @tisho
1.) datasheet p. 9 says: "IF bandwidths of 200kHz are recommended for use at Fif = 450kHz only. As far as I understand, the Msi001 runs in "zero-IF-mode" and 200kHz bandwidth. If so, datasheet p. 10 says, the smallest bandwidth is 1.536MHz and reg0 [16:14] should be set to 011. Is that true? And how could I alter the Msi code to account for this?

2.) If no. 1.) is correct, we have a 1.536Mhz signal for the I & Q inputs of the PCM1808 ADC, which runs at a sample rate of 96kHz to max. 256kHz. This leads to considerable aliasing (and could possibly explain the many birdies I see)! So we need two good anti-alias-filters for the I & Q inputs. Is that correct?

Till now I was sure that we work in "zero-IF-mode" with bandwidth of 200kHz. My opinion was based on the information from the Reg.0 table (page 18)
MSI001_Init.jpg
But you are right that in the tables on page 9 and 10 it is a bit different.

4.) datasheet p. 16, it says: "Important note: Register 5 bits 19 and 21 need to be set high for correct operation of the part." [in the context of AFC]. However, I could not find this in the Msi code. Did I overlook this, or is it not needed?

The setting of the Register 5 it is done in:
Code:
reg5 |= (0xFFF & thresh) << 4;
  /* Reserved, must be 0x28 */
reg5 |= MIRISDR_RF_SYNTHESIZER_RESERVED_PROGRAMMING << 16;  //bits 19 and 21 of are set in the line 444 of my msi001 document

The calculation of "frac", "thresh" and "AFC" is done in the following section.
Code:
/* We find the greatest common divisor for thresh and frac */
   for (a = thresh, b = frac; a != 0;)
  {
    c = a;
    a = b % a;
    b = c;
  }

  /* divided */
  thresh /= b;
  frac /= b;
  
  /* In this section we reduce the resolution to the maximum extent registry */
  a = (thresh + 4094) / 4095;
  thresh = (thresh + (a / 2)) / a;
  frac = (frac + (a / 2)) / a;

  //Calculate the actual Flo basd on the upper determined coefficients ("frac" and "thresh") (calculate without the fine tuning value - AFC)
  uint64_t Mult = (4*XtalFreq)/lo_div;
  uint64_t Flo = Mult*n + (Mult*frac)/thresh;

  if (switch_plan.upconvert_mixer_on)   //FLO = FC +FIF MHz for non AM modes and FLO = FC +FIF + FIF1 MHz for AM modes
    {
      Flo -= Fif1;
    }

  int DeltaF = p.freq - Flo;           //Calculate the difference between the "set" and the "result"(without fine correction) frequency 

  if (DeltaF<0)                       //If the difference is lower than 0 => the result frequency is higher than the "set" (no able to reduce with the fine tuning AFC) 
    {                                 //reduce frac with 1 to be able to add fine tuning (AFC) 
    frac--;
    //Recalculate the Flo again
    Mult = (4*XtalFreq)/lo_div;
    Flo = Mult*n + (Mult*frac)/thresh;
    if (switch_plan.upconvert_mixer_on)   //FLO = FC +FIF MHz for non AM modes and FLO = FC +FIF + FIF1 MHz for AM modes
      {
      Flo -= Fif1;
      }
    DeltaF = p.freq - Flo;            //Recalculate the delta again
    }

  uint64_t Fstep = (4*XtalFreq)/(lo_div*thresh);    //calculate the Fstep

  uint32_t AFC = (4096*DeltaF)/Fstep;               //Calculate the needed fine tune freq. to match the set frequency
There basically we calculate first the "frac" and "thresh" we see what is the difference from the desired frequency and the AFC is determined
 
totally false... those are reg 0 init writes and maybe superfluous ...

Regards.

0xf380 and 0x6280 seems related to reg1 (registers are sent lsb to msb, so 0x8 is 1000 = reg 1 as original linux driver reg write funtion does:

mirisdr_write_reg(p, 0x08, 0x00f380); /* kernel driver */

int mirisdr_write_reg (mirisdr_dev_t *p, uint8_t reg, uint32_t val) {
uint16_t value = (val & 0xff) << 8 | reg;
uint16_t index = (val >> 8) & 0xffff;

libusb_control_transfer(p->dh, 0x42, 0x41, value, index, NULL, 0, CTRL_TIMEOUT);

}

Seems we have a serious bug here, as we can't send 0xf380 using the teensy write reg version as it will write to register 0x00 instead to the correct one, the gain register 0x01.

We have to shift left 4 bits and then OR 1 before sending to the msi001 ... :confused:
 
0xf380 does not make sense to me at all:
1111001110000000 --> so reg0, no RF synthesizer enabled??? [bit 10]

and then, reg0 is written again?
0x6280
--> 110001010000000

and then, which register is written then?
0x0e --> 1110 : this is an invalid register . . .

and then, which register is written then?
0x03 --> 11 : reg3? but what does it write? all zeroes?

It seems I might be missing some basics on register settings.

Can somebody please explain to me what these lines are supposed to do? These lines are called EVERY time the frequency is tuned in the Msi001.

Code:
  /* kernel driver adjusts to changing frequencies  */

  mirisdr_write_reg( 0xf380);
  mirisdr_write_reg( 0x6280);
  mirisdr_write_reg( switch_plan.band_select_word);

  mirisdr_write_reg( 0x0e); //OK
  mirisdr_write_reg( 0x03); //OK

Also I have not understood what a "band select word" is supposed to do.
0xf780 -> 1111011110000000
reg0: AM NOT selected, but Band4/5 and 19.2MHz crystal???
 
@tisho, @Esteban:

I have a bugfix for the tuning step / AFC

Code:
  int64_t DeltaF = p.freq - Flo;           //Calculate the diference between the "set" and the "result"(without fine correction) frequency

 [B][COLOR=#ff0000] DeltaF -= XtalFreq;[/COLOR]
[/B]
  if (DeltaF < 0)                     //If the difference is lower than 0 => the result frequency is higher than the "set" (no able to reduce with the fine tuning AFC)
  { //reduce frac with 1 to be able to add fine tuning (AFC)
    frac--;
    //Recalculate the Flo again
    Mult = (4 * XtalFreq) / lo_div;
    Flo = Mult * n + (Mult * frac) / thresh;
//    if (switch_plan.upconvert_mixer_on)   //FLO = FC +FIF MHz for non AM modes and FLO = FC +FIF + FIF1 MHz for AM modes
    {
      Flo -= Fif1;
//      Flo += Fif1;
    }
    DeltaF = p.freq - Flo;            //Recalculate the delta again
    [COLOR=#ff0000][B]DeltaF -= XtalFreq;[/B][/COLOR]
  }

I have subtracted the Xtal freq from the DeltaF each time the DeltaF is calculated. After adding this, the tuned frequencies are spot-on and also the tuning does not jump any more.

Could you try and report back whether it works for you?

Now to the other bugs:

* I have NO mirror rejection
* the gain setting is also buggy and sometimes not set properly or reset during tuning

PS.: I have completely eliminated the dubious register stuff mentioned in my previous post #515
 
Regarding the non-existing mirror rejection with the Msi001:

* Do you experience also missing mirror rejection?
* in your video, Esteban, I can see that there is some mirror rejection on shortwave, but on medium wave, you can clearly see in your video, that the rejection is less than 20dB. In the QSD Teensy Convolution SDR, we have up to 60dB rejection
* I wonder whether it is related to the symmetric nature of the I and Q output of the Msi001. You connect the two output lines of each output to ground via a 10nF cap and via a 510 Ohms resistor. And then you just connect one of the output lines to the ADC input via GND, thus forcing the symmetric output of the Msi001 to the unsymmetric input of the PCM1808 ADC. Not being a specialist in that, I suspect that this could severely influence the phase relationship between I and Q!? That would lead to bad mirror rejection like we can observe it.

What do you think?

EDIT: I just saw, that you, Tisho, use two OP-Amps on your PCB to make the symmetrical I & Q signals asymmetric. Do you see good mirror rejection with that approach?
 
Last edited:
Hi

* Mirror rejection is fine here; must be something hardware related. Could you test teensy board with another IQ source?

https://youtu.be/v2A7rdLU5Jg
https://youtu.be/CFnTTz2hoF4
https://youtu.be/yCzdaNQQekw
https://youtu.be/TM2pgsi4fRg

* No images in my video, just there are two near strong transmitters in MW, at 621 and 720 khz.

* Only Ip and Qp are connected in your board ... Sure, it would be better to use op-amps or diferentlal to single ended transfomers.

About the weird register writes:

* library has support for the msi2500 + msi001 so, here we have USB control, msi2500 and msi001 configuration writes. For example:

@adc.c

Code:
    mirisdr_write_reg(p, 0x08, 0x006080); /* kernel driver */
    mirisdr_write_reg(p, 0x05, 0x00000c);
    mirisdr_write_reg(p, 0x00, 0x000200);
    mirisdr_write_reg(p, 0x02, 0x004801);
    mirisdr_write_reg(p, 0x08, 0x00f380); /* kernel driver */

...

    /* uspíme USB IF a ADC */
    mirisdr_write_reg(p, 0x03, 0x010000);

...

@hard.c

		/* maximum rate 6.048 Msps | 24.576 MB/s | 196.608 Mbit/s  */
#if MIRISDR_DEBUG >= 1
		fprintf( stderr, "format: 252\n");
#endif
		mirisdr_write_reg(p, 0x07, 0x000094);
#endif
		mirisdr_write_reg(p, 0x07, 0x000085);
		p->addr = 336 + 2;
		break;
	case MIRISDR_FORMAT_384_S16:

...

I guess those are related only to USB/msi2500 configuration... But on the other hand, the msi001 writes have this format:

@gain.c

Code:
 reg1 |= MIRISDR_DC_OFFSET_CALIBRATION_PERIODIC2 << 14;
    reg1 |= MIRISDR_DC_OFFSET_CALIBRATION_SPEEDUP_OFF << 17;
    mirisdr_write_reg(p, 0x09, reg1);

    /* DC Offset Calibration setup */
    reg6 |= 0x1F << 4;
    reg6 |= 0x800 << 10;
    mirisdr_write_reg(p, 0x09, reg6);

So seems that 0xf380 and 0x6280 are not msi001 related and can be removed from code.

I'll return to my qth from short vacations tomorrow and then test source without those lines and your bugfix for the tuning step / AFC. Great find!.

Regards.

Regarding the non-existing mirror rejection with the Msi001:

* Do you experience also missing mirror rejection?
* in your video, Esteban, I can see that there is some mirror rejection on shortwave, but on medium wave, you can clearly see in your video, that the rejection is less than 20dB. In the QSD Teensy Convolution SDR, we have up to 60dB rejection
* I wonder whether it is related to the symmetric nature of the I and Q output of the Msi001. You connect the two output lines of each output to ground via a 10nF cap and via a 510 Ohms resistor. And then you just connect one of the output lines to the ADC input via GND, thus forcing the symmetric output of the Msi001 to the unsymmetric input of the PCM1808 ADC. Not being a specialist in that, I suspect that this could severely influence the phase relationship between I and Q!? That would lead to bad mirror rejection like we can observe it.

What do you think?

EDIT: I just saw, that you, Tisho, use two OP-Amps on your PCB to make the symmetrical I & Q signals asymmetric. Do you see good mirror rejection with that approach?
 
Last edited:
Tisho get the IQ schematic from the malahit sdr receiver. I have ever tried porting Teensy Convolution SDR to it but failed. Many code I don't understand.
 
It seems I had a combined hardware and a software bug that prevented mirror rejection. Now it runs and the mirror rejection seems normal! Excellent.

Also, the mirror rejection seems to be highly dependent on the settings of the different gains, we seem to have to put a lot more work in setting sensible gain values in order to optimize reception quality!

Next problem is that I can receive all the way down to about 3.5MHz, but lower than that gives no reception . . .
 
It seems I had a combined hardware and a software bug that prevented mirror rejection. Now it runs and the mirror rejection seems normal! Excellent.

Is that what I'd call image rejection / sideband suppression? Not heard the term before.
 
Is that what I'd call image rejection / sideband suppression? Not heard the term before.
Mirror rejection is the same as image rejection. I think it is more of a DSP term than a radio term, but it means the same thing.
 
Hello guys,
sorry that I was not active last days, I am still in vacation and don't have much time :)
Frank I am happy that your set up is already working fine

Next problem is that I can receive all the way down to about 3.5MHz, but lower than that gives no reception . . .

All reception that I got in the range under 3MHz was with the BPF board and the active antenna (my version of the mini Whip) that I showed before.
With long wire antenna I also couldn't receive anything down there, but with the active antenna I got the 77kHz DCF
 
@DD4WH and everyone.
I am not having great performance from my modified QRP Labs QSD receiver and Teensy setup. I finally bought myself an oscilloscope, an RF generator, a large pile of filters, a small pile of attenuators, and a step attenuator so I can do some actual testing to figure out what is going on.

I have some areas in the spectrum where the noise floor jumps way up. Using my shiny new oscilloscope, I found this to be due to ringing on the LO input on the receiver due to me using a ~25 cm coax between the oscillator and the receiver. The capacitance of the cable causes ringing on the LO signal and the Johnson counter makes some very strange waveforms out of this ringing. This only occurs over some seemingly random frequency ranges. The Si5351A is supposed to drive 50 Ohms but it does a very poor job of it. I tried a 50 Ohm resistor at the receiver input and this dropped the LO level too low for the Johnson counter. I think I will add a buffer amp to the Si5351A so I can terminate it with a 50 Ohm resistor at the receiver. I wonder if anyone else has had this problem or is it just me trying to drive a long cable with a wimpy oscillator? Once I fix this, I will do some more serious receiver testing.

I have an idea for making a wider bandwidth spectrum display without compromising receiver dynamic range. TI recently came out with the PCM1840 which is a version of the PCM1808 that has 4 channels instead of 2 and is rated for a sample rate of 192 kHz instead of 96 kHz. It looks like about the same interface as the PCM1808 so we already know how to talk to it. It has 113 dB signal-to-noise (at 192 kHz) which is much better than the ~90 dB of the PCM1808. Sampling at 192 kHz will produce a 57.6 kHz wide IF bandwidth with amplitude accuracy of +/- 0.05dB (according to the spec sheet) but with IQ sampling this should be 115.2 kHz (or more if we use Teensy filters instead of the built-in filters). My idea is to have two IF channels, one wide and one narrow. The wide IF frequency will be for the spectrum display. The narrow IF will have a selection of analog band pass filters on the input for high performance receive. Putting the filters in the IF input gives us a very high performance receiver but prevents the nice wide spectrum display. But two IFs gives us both.

My goal here is to make a communication grade 100 kHz - 54 MHz receiver for CW and SSB work. A full compliment of IF filters will be something like: 250 Hz, 500 Hz, 2.7 kHz, 6 kHz and 15 kHz. This is easy with an IF frequency of 48 kHz or similar.

I have also been working on a higher performance QSD receiver for the Teensy SDR. I did some modeling and found that the QSD is very sensitive to having the FET switch timing perfect; a few percent off on the timing and the performance drops off drastically. I also found some serious issues in my detector with slow rise times and fall times that cause the switching to be soft and inaccurate. I have considerable work to do on quantifying this, but I'll report back when I have some presentable results. I found some FET switches that I think will give higher performance than the usual suspects or the Potato chips. See the SN74AUC2G53. Their switch time is very fast and their propagation delay is around 0.1 ns. The down side is that they run at 2.5V max, but I think this is okay.

My thought is to use the Si5351A in quadrature mode for the higher frequencies and use a divider and Johnson counter for the lower frequencies.

I plan to produce some PCM 1840 boards if folks are interested and this sounds like a good idea. I'd be happy to send you a PCB DD4WH if you want to experiment with this idea?

73,
WH7U

https://www.ti.com/lit/ds/symlink/p...2Faudio-ic%2Fconverters%2Fadc%2Fproducts.html
 
Back
Top