Digital filter just has got 2 channels. 10kHz could be done on a PSoC5 with a program, the CPU is fast enough.
(i) What is the source of 24-bit data? Is it a digital bus?
(ii) It appears that all operators are linear, therefore sum of 3 channels can be taken before averaging of each channel, and having the same result without spending PSoC resources.
odissey1, thank you for your interest for my problem.
1. Data comes from the ADC (3 sensors - channels) via SPI to DMA.
2. The Internal Psoc Main Processor we cannot use because it has to do other things and has no resources for that.
For the processing in the DFB we have the following possibilities:
1. DFB input is 72-bit stream (data block with all of 3 channels samples)
2. DFB input is 24-bit stream (data block is just one channel sample)
We write 72-bit in one stream and processing it in DFB. After n-iteration, average values (results) for particular channel are stored in RAM.
We write 24 bit in DMA (just one channel) and trigger the DFB. When the DFB is finished with the first processing of first channel
we proceed with the next 24 bit (next channel) and then the same for the third. After (3 x n)-iteration, results are stored in the RAM.
Very important is that the entire procedure (all 72 bits) takes not longer than 100µs. But I mean that this is not a problem, because the DFB itself needs just some ns for processing.
Thank you very much for your help in advance!
DFB_detail.pdf 94.2 K
now I understand the problem better. In short, you want to improve 24-bit ADC resolution by oversampling.
The reason I asked is that I recently made a component for ADC_SAR oversampling and thought that it could be useful here (which is not the case). The component takes data from digital bus (not DMA), uses IIR filter (you want FIR filter) and realized in PLD (no space for 3 32-bit blocks).
I see some issues using DFB for your goal. The DFB has 24-bit calculation engine - the output will be 24 bit no matter how long the average is. If the goal was to ultimately obtain ~32-bit resolution, it won't happen. Then there are only two channels in DFB, so you have to somehow buffer or interleave incoming data etc., which adds headacke.
I believe that this task fits well into UDB Datapath, consuming 4 UDB cells for each ADC (50% of all UDB resources total). (DMA-FIFO-ALU-shift.) Unfortunately, I don't have example for that. ADC_SAR in PSoC4 has such averaging feature, so you may inspect how it's made there.
I align with Bob Marlowe on that 3x10kHz is not terribly fast, and ISR+CPU will be able to handle simple arithmetic involved. I would try this first. As an example, take a look on this BLDC control app. note, which uses PSOC4 ISR for controlling 4 phases at 10kHz rate.
Yes we want to improve the resolution by reducing the signal noise.
The ADCs are extern and well filtered using hardware for the high frequencies (~10kHz 3dB).
We want to achieve a damping for 1kHz therefore we have to use a digital filter. HW filter changes are not possible because of additional complex reasons.
The PSOC5 itself is used extensively. All the UDBs are used and the processor itself stands under heavy load.
At the moment the damping is working and it is realized with DMA and the processor itself but we need processor's power for other open issues.
As you see the DFB is a tempting option. What I should mention is that we need only 24-bit as output of the DFB because the shift to a 32-bit value can be done by DMA itself and this is already working.
Also important is that we can shift the lower 8-bit of a sample value out by DMA (only noise) before sending it to the DFB. In combination with the fact that we have only a maximum of 100 samples for the mean value we ensure that an overflow cannot occur.
As I see this now we have two possibilities:
First is to implement two counters in the DFB one for the channels and one for the samples of each channel. We need three DFB RAM fields for storage the three subtotals. Everything is synchronized so we know each value of the corresponding channel due to the channel counter. If the second sample counter reach his maximum than we have to divide the subtotal by the counter value and send the result out. Due to the synchronisation the DMA, after the DFB, knows to which channel this result value correspond and can save the result in the global RAM at the right position.
The second possibility is that we save each input value (3 blocks one for each channel) in the DFB RAM and sort the values. If the sample counter has his maximum we can choose than the medium value. In thise case no sum is needed but we need much more space in the RAM. Therefore a n of about 10 is the maximum which would be achievable. This solution is therefore not the preferred one.
What we achieved until now is to multiply and divide an input value in DFB and send the result to the output. What we will try to do next is to store an input value in the DFB RAM and read it out and write to the output.
Hope this detailed description was helpful. It would be quite happy if you can help us to achieve the goal and I have an open mind for better solutions of this problem.
I ´ve prepared three useful simple examples for DFB programming in assembler. Examples might be useful for anyone who is a beginner in DFB assembler. Very recommended is also the article on the web site: http://arttools.blogspot.co.at/2016/02/.
With these three examples you can find the answers on the following questions:
1. How to multiply input value with pre-defined constant stored at DFB RAM?
2. How to read data from RAM and transfer it to the DFB output register?
3. How to save data present at the input Stage A register into the specific RAM location?
Thank you for assembler codes, a demo project would be great!
A few comments:
When waiting for values to arrive at the input register the loopjump jmpl(in1,Multiply) should be used, otherwise the code will fall through to next block even with no new data present in the input.
eob is only necessary to specify for unconditional jumps.
Try the attached DFB assembler code, it reads from staging register A, adds the value into one of three RAM locations (channels) and switching to the next channel.
When 8 samples have been summed, the totals are output to holding register A, and the accumulation is restarted.
interleave.txt.zip 700 bytes
Your approach reduces the output frequency by factor of eight (8).
When you program a gliding average the output frequency will be the same as the input frequency.
It does reduce the output frequency by 8, but this is what the OP asked for.
Magnus, I have no experiences in programming the DFB. But I thought that a gliding average filter would be quite useful as a filter implementation.
1 of 1 people found this helpful
First, thanks for your numerous postings on this forum - they have been a great help and I appreciate your devotion.
Inspired by your comment above I took a crack at a generic single-channel gliding / moving average proof of concept program. It is here:
For a 5-sample moving average window my implementation has an initialization delay of 3 instructions, 30 instructions (5 samples * 6 instructions each) to populate the initial calculation values (which are discarded), and thereafter a new moving average is output every 6 instructions regardless of the number of samples in the window. It should support up to a 127 sample window at the same 6-instruction processing time from input to output if the coefficients are updated accordingly. This was the smallest cycle count I could fit the calculations into.
Since this example is for illustration purposes and is single-channel, it thus does not meet this post's original requirements. I think the requirements could probably be met, but interleaving the 3 channels would prevent a lot of the pipelining and macc optimizations. For 10kHz though a much longer instruction count for the calculation doesn't seem like a problem.
Note: I created an enhanced DFB mini-development environment and used it to program this example - more details are in this post: