Hackaday demo: Signal generator

Dependencies:   SDFileSystem mbed

Revision:
0:8baa10bd07de
--- /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
+        }
+    }
+}