04/24/2016 at 18:41 •
For a quick test if the PWM-is capable of outputing the Bitstream fast enough I wrote a small testprogram ( by modifiying the rpitx-Source). This testprogram initializes the PWM-Periperal with 125 MHz Clock (125Mhz clock and 32 oversampling translates to 3,9 MSPS)
The testprogram generates alternating pattern of 0xFFFF0050 and 0xFF000020 - the
result looks quite workable (see picture below)
there are some glitches from time to time - which can be expected on an
multitasking OS - but maybe with DMA this issue could be solved aswell.
04/24/2016 at 18:32 •
SigmaDelta-modulators use a method called oversampling to generate the desired dynamic range.
For the first experiments with the SigmaDelta-Modulator I tried to implement a 2nd Order 32 Oversampling SigmaDelta-Modulator - which should result in a SNR compareable sligthly above 8Bits-DACs.
N-times Oversampling means that the for each sample the SigmaDelta() has to do the necessary calculations N-times - which can be a quite CPU-Cycles hungry venture - so in order to address this issue - I wrote a small SigmaDelta-function compiler - which gernerates an ARM optimzied C function using inline assembler.
I managed to write a function that only needs 6 CPU-Cycles per sample for one iteration of the oversampling process on ARM11 - and on CPUs like the Cortex-A7 (partial dual-issue) or Cortex-A53 (dual-issue) the calculation can be done with 5 CPU-Cycles. Additional ~32 Cycles per Sample for all oversampling iterations must be added as well mainly for storing results and entering and exiting the C-Function
This function allow us on RPI2 (Cortex A7) and RPI3 (Cortex A53) to implement a 4MSPS 2nd-Order 32x Oversampling Sigmadelta-Function which consumes roughly 768 MHz of a single CPU Core. ( 768 MHz = 4M*(5 Cycles*32+32 Cycles))
On RPI1 (ARM11) which would need overclocking to 900Mhz a 3MSPS 2nd-Order 32x Oversampling Sigmadelta-Function should be possible - this would consume 672 MHz of the CPU. ( 672 MHz = 3M*(6 Cycles*32+32 Cycles))
Using Octave I can evaluate the ouput of this SigmaDelta() without actually building it - I feed the SigmaDelta() with multiple sine-signals (spaced at 150kHz) and the result looks like this:
The Source-Code for the optimized SigmaDelta-Function Compiler can be found on github: