Hackaday demo: Signal generator
Dependencies: SDFileSystem mbed
Diff: output.cpp
- Revision:
- 0:8baa10bd07de
diff -r 000000000000 -r 8baa10bd07de output.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/output.cpp Fri Sep 11 02:32:43 2015 +0000 @@ -0,0 +1,62 @@ +#include "mbed.h" +#define _EXTERN_ extern +#include "main.h" +#include "output.h" + + +// Output "engines" + +// Mbed timers are not reliable below a few dozen uS +// At one point I did this table but it is better to do a iinear regression +// for the whole range not just the ones that suffer from the timer jitters +// You would need to refigure the linear regression any time you change the loop but +// for the current setup (http://mycurvefit.com/ is handy for that) +#define M 23.79f +#define B -8.9878f + +// If you want to set the M and B (see above) you can set CALIBRATE to 1 +// and set M and B to 1.0 and 0. Then enter some different timebase +// values (t command) and measure the timing +// Then fit the curve using M and B +#define CALIBRATE 0 + + +AnalogOut aout(DAC0_OUT); // Analog output + + +// inline assembly for nop (plus function call overhead) +void nop(void) +{ + __ASM volatile("nop\n"); +} + + +// Execution engines + +static void exec0() // timebase == 0.0, go as fast as possible +{ + while (1) { + aout.write_u16(buffer[bp]); + bp=(bp+1)&BUFSIZEMASK; + } +} + +void exec() // All other time bases +{ + unsigned i, newbase; + if (timebaseus==0) exec0(); // go as fast as possible -- never returns +#if CALIBRATE==1 + float m=1.0f,b=0.0f; + pc.printf("Using M=%f B=%f\r\n",m,b); + newbase=(unsigned int)((m*timebaseus-b)+0.5f); +#else + newbase=(unsigned int)((M*timebaseus-B)+0.5f); +#endif + while (1) { + aout.write_u16(buffer[bp]); + bp=(bp+1)&BUFSIZEMASK; + for (i=0; i<newbase; i++) { + nop(); // could shave a little off maybe by moving inline here + } + } +}