Carlos, I believe that 10-bit DMA configuration for ADC_SAR-DFB transfer should be the same as for 12-bit.
This can be achieved either by loading the ADC converted values to Data RAMs (DFB_LoadDataRAMA() / DFB_LoadDataRAMB() ) or through staging registers (DFB_LoadInputValue() ). Since the no of samples is not a power of two, you can either go for CPU or IIR filter with appropriate weights for division. (DFB has got an inbuilt shifter, which could have used for division otherwise). Additionally, set coherency to mid byte to take care 10 bit resolution using API DFB_SetCoherency().
Hi @Geona, yes i notice that 10 is not a power of two after making the post, it can be 8 or 16 with no problem, i will try to make a project and post more questions when i get stuck.
@oddisey, i will try the 12bit resolution :)
Thanks for the help
1 of 1 people found this helpful
The following project could be a help to play with.
I am not finished testing it completely or writing up all notes and comments, but it seems to run quite ok.
I test it by connecting a voltage divider, run it in the debugger and check the resulting values with debugger.
Great @Magnus, i never thought about multiplying the input by 0.1 (to get rid of the division), it's a very clever "trick". I guess the main thing with DFB is think with a Multiply and Accumulate mindset.
I printed the DFB code in a paper to start getting familiar, understanding the VLIW set is hard at the beginning, at least it's being hard to me.
Thanks for the example, it's very helpful
Just tested you project, i changed a couple of things to get it "working":
* On the last instructions when you write the result to the bus of the DFB, you use the command write(bus), reading the datasheet seems that is better to use write(abus) (check the table about the write instruction in page 39).
* And cleared the interrupt status after enter in the for loop.
Attached is your example project with this fixes.
Thanks a lot for the projects you upload here in the forum and your blog.
Good that you are getting things to work. Your comments are correct, but I don't think the changes are really necessary, it works for me without changes and:
* addr(1) write(bus) is equivalent to write(abus), see the last entry in the table on p.39
* The interrupt status flag is cleared by hardware when reading the holding register
The interrupt flag is only used as a status flag in this example and not connected to the interrupt system, it would be nice to attach an interrupt object and then handle the output in the interrupt handler, just to se how this works.
I getting to like the DFB, seems it can do some nice things, and its nice that you are using it not just saying that DFB is hard and dont bother.
Thanks for letting me know the interrupt status flag is cleared by hardware reading the HOLDA reg, it can save some time.
About the addr(1) write(bus) vs write(abus) i think is matter of personal preference hehe, i think using the former is maintained just for backwards compatibility by cypress, but at the end both commands do the same, anyways i'm not an expert here lol.
I'm modifying the project to run at 10sps, then adding a second TD on the DMA to save the ADC results on a memory array, btw i'm using a interrupt component on the interrupt output of the DFB to set a flag on the interrupt handler and clearing the interrupt status flag, will upload the project when it's finished.
Thanks again for the help.
Here is the almost finished project, the ADC runs at 10sps, the value given by the DFB is printed to the console via UART@115200, it seems pretty accurate, offset of some 10mV.
@Magnus, the data on the hold registers are in q23 or hex format? i'm still trying to figure out that data format, iirc data in acu area can be in hex format, but q23 in data_a and data_b areas.
All data is in 24 bit signed binary, 48 bit inside the MAC but we never see that. When entering data for the RAM blocks the simulator only accept unsigned numbers in decimal or hex format, I have not been able to get it to accept any q23 number format, so that scaling must be done by the programmer. The generated code has data in unsigned hex format and can be seen in the DFB_xxx_RAM.c file.
The way the multiplication in the MAC works, signed multiplication that returns the top valid 23 bits is mathematically the same as dividing the product by 2^-23, that is A*B>>23. The natural way to interpret these numbers, without having to worry about the 23 bit scaling is to interpret all numbers as q0.23 decimal numbers.
So the operation of the MAC can be interpreted as
y = y + (a*b>>23) as signed integers, with 24 bits of decimal fraction in the lover bits of the MAC so its not really integer arithmetic
y = y + a*b as q23 numbers
The high alignment shifts the input up to make a q16 number, or a signed 16 bit integer, to the same q23 value, with lover 8 bits set to 0. The high output alignment shifts the q23 to a q16 value corresponding to a valid signed 16 bit integer.
The results are always sign extended to 32 bits if read as 32 bit integers from the holding registers.
So the short answer is that the results are 24 bit signed integers or q23 depending on how you decide to interpret them.
Sorry for the delayed reply, thanks for all the information about the DFB, is getting less difficult to use :D.
Good hear your starting to feel confident with the DFB.
I think there could be a systematic way to develop DFB algorithms, I will try to develop it and formulate over xmas, but some of the ideas are:
- Identify key algorithm computation steps
- Design the data flow - there are no instructions for the datapath, but the datapath contains the ALU of previous instruction
- Map data to RAM locations
- Think of states - identify loop states, and preparations for computations and postcomputation operations
- Use the ALU as a loop counter and to address RAM blocks
Lately I have been using a spreadsheet with one column each for
STATENAME, RAMA, RAMB, ACU, ALU, MAC, DATAPATH jumps and comments
There I try to fill in the necessary parts of the algorithm structure, and only enter what is necessary. After that I try to fill in the complete code in the DFB assembler using the spreadsheet as a blueprint.
I have a few example project that I work on - PID controller, square root function and a filter implementation. They need some work to be presented but they could perhaps illustrate the above ideas.
I saw your new post on your blog last night, is this part of the project you are working on?
Have you think about posting that information here on the forum? it would be great as DFB examples are almost not existing!