Ok, so I spent a good portion of the Memorial day morning coding this non-blocking, DMA port for the BF706 UART. Instead of making just another boring example, I decided to make a fun example for newcomers and experienced DSP developers alike and create an interactive console where an LED is flashed on our ADZS-BF706-EZMINI. Flashing an LED is fun, but not that intuitive unless...How about typing the flash rate at the console too ? This means we can change the algorithm parameters in real time and interact with our DSP in an less boring and exciting way...I found PatrickG Assembly PDF quite informational and useful, so I modded the assembly code to accept external blinking rate parameters directly from the console! Ok, maybe not directly, but indirectly via a C-based command interpreter!
The idea behind this is that we can pass external parameters from console command line parser straight into an assembly function from C code directly. If you were wondering how this is done, check out the source. Modify it to suit your tastes and make it better. Demo your accomplishments...
The assembly code takes in parameters passed into data registers forwarded on the stack. I made sure I saved the LED blinking rate into a pointer register and saved it for future use in the looping logic...
So this is the fun stuff you would have to technically write to create a basic command interpreter via C code. There are many ways to do this and this is just a rough example that seems to work as long as you don't type too fast during long blinking delays. In DSP we do not wish for loopy code that takes significant periods of time, so make sure you set up your blinking rate quite high...I came up with 100,000 counts minimum (very fast blinking/pulsing) to about 1,000,000 counts maximum for a more significant semi non-blocking delay. Experiment and tune to taste...It is not perfect, but it is doable and performance can be greatly increased by segmentation of the loopy assembly logic and making more granular returns! This should not be too much of a problem in fast assembly routines.
I have included some verbosity states that show the terminal user what is going on if they successfuly entered a correct command. If you do not see the bracketed state, you are doing something wrong. Either your UART baudrate is set incorrectly or you are typing nonsensical commands in the console, so beware! The acceptable baudrate for this example is 115200. Make sure your setup up your PUTTY terminal as follows :
After setting up your UART, make sure that you have my project Un-RAR'ed and successfully loaded into CrossCore Embedded Studio.
If the project load is successful, go ahead and activate your debug mode and run this puppy...
Here is a brief command summary that you can enter in the console :
rate=0 (will take you to default rate which you can change)
quit (this is final and will require a debug restart)
Go ahead an experiment with your own ideas by modifying rates, adding commands and hook it all together. Hook an FIR filter into it and pass some nice coefficients at the command line. That might be my next example actually so hopefully by next week I will have something new up...Experimentation is key! Improve efficiency and let me know how you did it and we can all learn something new!
Keep in mind that rate=xxxxxxx can be changed in real-time without led off having to be issued.
when issuing a rate=xxxxxxx command, the LED can be off, so make sure to turn it on to see the results with the led on command.
The last part of my code is simple clean up and puts a slight delay to allow the last DMA issued TX buffer to finish successfully otherwise it chops off the send and issues garbage past the carriage return.
Well that about does it in a nut-shell...Of course we can drill down into the devil in the details, but that will be another days discussion and I'm happy this is done for now. Just wanted to get it out of the way quickly so that we can get to all the juicy fun stuff later! Happy DSP'ing! Cheers and have a Great Memorial day!
The idea behind this update was to modify the previous UART code, but make the buffering of incoming data faster, so that someday soon I can run a pipeline straight into the console from another process and update my DSP internal variable via an named pipe process. I'm not going to get into too much of the details of this since I have a solution based on C# WPF that makes a dynamic process more pleasant by auto-feeding rapidly changing variables inside collections of structured arrays utilizing and serializing data streams from those variables based on an interactive event triggering mechanism. What this requires is a means to update feedback events very quickly as the graphic utility functions send their updates via these internal triggered events. In a nutshell this means that my receiving logic via UART needs to respond very fast without having major delays that could hiccup during the transmission of serial events. To achieve this, I created an re-entrant counter function based on static variables. Unlike my previous example, this version, updates the led blinking counter/timer via post-decrements and when it returns to zero, toggles to a different state and vectors after the reset of the counter into a different section of assembly code.
The two sections are called _ledon and _ledoff. They are no longer blocking with loop counters structure and return right the way for another iteration of the unblocking static counter until it resets, then it toggles back to the other section. A toggle is thus an simple two state, state machine.
Following bad naming convention, I should not have called it MyPotential...blah...blah...anything, But it goes to illustrate the idea of re-entrant code. For simplicity I will show two different processes but this could really be merged into one section instead of two based on the toggle state! So yeah, its a bit inefficient having an code butterfly laid out for visualization, which generally serves the illustrative purpose of demoing simple symmetric processing logic.
If you decide to test this implementation, it will run full speed no matter which counter delay parameters you pass in, because it bypasses un-necessarily long loop counters inside the assembly logic. This whole static loop logic could easily be implemented entirely in assembly! I may do just that on the next released version!