Skip to main content
_andreas
Senior
September 22, 2022
Question

In theory, you can use all 26 bit of the STM32U MDF in the CIC stage. In practice, I recommend to stay < 25 bit to avoid artifacts and saturation.

  • September 22, 2022
  • 10 replies
  • 3309 views

..

This topic has been closed for replies.

10 replies

ST Employee
September 29, 2022

Hello @Andreas Köpke​,

Can you provide more details about your observation, please?

In which condition you saw artefacts and saturation?

Thank you for your feedback,

Gwénolé

ST Employee
September 29, 2022

Another point,

The MDF FIFO is set to 24 bits like CIC output can be extended to 26 bits. Then, to fit with FIFO it's mandatory to use the SCALE block.

In case you enabled the INT block after CIC + SCALE blocks, then there is no possibility to adjust the output size from 26 bits to 24 bits.

Best regards,

Gwénolé

_andreas
_andreasAuthor
Senior
September 29, 2022

I use the B-U585I-IOT02A, modified VREF+ pin to be powered from internal VREFBUF 1.5V. Then I use the DAC1 to produce a sine wave, it gets quite close to the rails.

0693W00000UFRPIQA5.pngThe offset of the oscilloscope is around 35mV:

0693W00000UFRPNQA5.png

_andreas
_andreasAuthor
Senior
September 29, 2022

Then I sample the signal with the ADC1 from PA4, also using 1.5V as reference voltage using a pretty plain setup (no oversampling etc) and feed it to the MDF.

When I use the CIC stage with SINC5 and a decimation of 4, this should result in 24bit wide internal results.

0693W00000UFRR4QAP.pngWhich gives a nice sine wave. However, if I use the same setup with decimation 5 then the internal results are 25.6bits wide - which is ok according to the datasheet - and I get this:

0693W00000UFRRsQAP.pngTo get this, I had to switch off the SATuration interrupt.

_andreas
_andreasAuthor
Senior
September 29, 2022

I was not overly surprised, in my CIC simulation playing around with an "internal" width of 26, only 25bits were useful, before it saturated.

_andreas
_andreasAuthor
Senior
September 29, 2022

There is a little room for improvement by using the correct offset.

_andreas
_andreasAuthor
Senior
September 30, 2022

@Gwenole BROCHARD​ I've updated the thread.

ST Employee
September 30, 2022

Hello @Andreas Köpke​,

From your inputs, here are my comments:

  • Sinc5 - Dec4 the maximum amplitude read is 1.3e8 which can be represented on 27.9 bits. The maximum value on 24 bits is +/- 8.39e6
  • Sinc5 - Dec5, firstly there is an offset in the injected signal. It seems that with a full scale signal (14 bits) + offset a wrap-around occurs.

I will reproduce on my side but I don't expect an issue with the MDF. I come back with further analysis.

Thank you for sharing the details.

Best Regards,

Gwénolé

_andreas
_andreasAuthor
Senior
September 30, 2022

I'm referring to the Reference Manual

RM0456

Reference manual

STM32U575/585 Arm®-based 32-bit MCUs

March 2022, RM0456 Rev 3, page 1239

where it says:

0693W00000UFWIlQAP.png 

with N = 5, D = 4 and DSin = 14 this results in

DScic = 24

and with N = 5, D = 5 and DSin = 14 this results in

DScic = 25.60964

Both values are within the recommendation DScic < 26bit.

_andreas
_andreasAuthor
Senior
October 5, 2022

@Gwenole BROCHARD​ 

My test code on PC looks like this:

// downsample: drop D values after integrator section, then comb
// https://www.dsprelated.com/showarticle/1337.php
// the CIC uses weight * <IC> elements
// delay lines hold one element for each <IC> element of the CIC
 
int32_t intDelay[weight];
int32_t combDelay[weight];
memset(intDelay, 0, sizeof(intDelay));
memset(combDelay, 0, sizeof(combDelay));
 
unsigned j = 0;
unsigned combCnt = 0;
double cicGain = pow(downsample, weight);
 
for (unsigned i = 0; i < NSIZE; i++)
{
 int32_t x = in[i][0];
 x <<= cicShift;
 for (unsigned k = 0; k < weight; k++) {
 x += intDelay[k]; // sum to element in delay line
 intDelay[k] = x; // store new sum in delay line
 }
 // downsampler
 combCnt++;
 if (combCnt >= downsample) {
 // comb section
 combCnt = 0;
 for (unsigned k = 0; k < weight; k++) {
 int32_t ov = combDelay[k]; // get old value from delay line
 combDelay[k] = x; // add new value to delay line
 x -= ov; // substract old value from new value
 }
 in[j++][0] = x / cicGain / (1 << cicShift);
 }
}

with in is the input (and output) data,

I want to run an FFT on it, so it's a two dimensional array of doubles. I only use the real part here. NSIZE is obviously the number of elements in the array.

weight is the CIC order, downsample is the decimatio ratio, cicShift is used to simulate the limited number of bits in the MDF CIC stage. cicGain has a correspondence to the MDF SCALE stage.

_andreas
_andreasAuthor
Senior
October 24, 2022

@Gwenole BROCHARD​ was so kind to simulate it and could not reproduce it - using the exact same setup. Since mathematics works, this claim is wrong: There must be differences in the setup.

Possible sources are:

  1. The ST simulation does not match the chip (my simulation code as posted here gives the result of the chip)
  2. The simulation test harness does not use the same width - the Reference manual gives only results for ADC with 12bit resolution, so this is a possibility.
  3. The simulated ADC has a difference in the top values (the datasheet mentions 0.2V from rail as maximum possible output for buffered DAC, but my board reaches rail). If the simulation uses the values from the datasheet, then there is a possible gap.
  4. Last but not least (for now) there may be a difference in the sampling rate, which I did not mention so far. I'm clocking the ADC1 from a PLL with 5.632 MHz, 5 samples ts, 14 bit resolution. This results in a sampling rate of 256 kHz. The input signal has a frequency of ~ 200Hz.