Hackaday demo: Signal generator
Dependencies: SDFileSystem mbed
output.cpp@1:c229c3ceb909, 2015-09-15 (annotated)
- Committer:
- wd5gnr
- Date:
- Tue Sep 15 15:21:34 2015 +0000
- Revision:
- 1:c229c3ceb909
- Parent:
- 0:8baa10bd07de
Making sure all changes are ready for publication.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wd5gnr | 0:8baa10bd07de | 1 | #include "mbed.h" |
wd5gnr | 0:8baa10bd07de | 2 | #define _EXTERN_ extern |
wd5gnr | 0:8baa10bd07de | 3 | #include "main.h" |
wd5gnr | 0:8baa10bd07de | 4 | #include "output.h" |
wd5gnr | 0:8baa10bd07de | 5 | |
wd5gnr | 0:8baa10bd07de | 6 | |
wd5gnr | 0:8baa10bd07de | 7 | // Output "engines" |
wd5gnr | 0:8baa10bd07de | 8 | |
wd5gnr | 0:8baa10bd07de | 9 | // Mbed timers are not reliable below a few dozen uS |
wd5gnr | 0:8baa10bd07de | 10 | // At one point I did this table but it is better to do a iinear regression |
wd5gnr | 0:8baa10bd07de | 11 | // for the whole range not just the ones that suffer from the timer jitters |
wd5gnr | 0:8baa10bd07de | 12 | // You would need to refigure the linear regression any time you change the loop but |
wd5gnr | 0:8baa10bd07de | 13 | // for the current setup (http://mycurvefit.com/ is handy for that) |
wd5gnr | 0:8baa10bd07de | 14 | #define M 23.79f |
wd5gnr | 0:8baa10bd07de | 15 | #define B -8.9878f |
wd5gnr | 0:8baa10bd07de | 16 | |
wd5gnr | 0:8baa10bd07de | 17 | // If you want to set the M and B (see above) you can set CALIBRATE to 1 |
wd5gnr | 0:8baa10bd07de | 18 | // and set M and B to 1.0 and 0. Then enter some different timebase |
wd5gnr | 0:8baa10bd07de | 19 | // values (t command) and measure the timing |
wd5gnr | 0:8baa10bd07de | 20 | // Then fit the curve using M and B |
wd5gnr | 0:8baa10bd07de | 21 | #define CALIBRATE 0 |
wd5gnr | 0:8baa10bd07de | 22 | |
wd5gnr | 0:8baa10bd07de | 23 | |
wd5gnr | 0:8baa10bd07de | 24 | AnalogOut aout(DAC0_OUT); // Analog output |
wd5gnr | 0:8baa10bd07de | 25 | |
wd5gnr | 0:8baa10bd07de | 26 | |
wd5gnr | 0:8baa10bd07de | 27 | // inline assembly for nop (plus function call overhead) |
wd5gnr | 0:8baa10bd07de | 28 | void nop(void) |
wd5gnr | 0:8baa10bd07de | 29 | { |
wd5gnr | 0:8baa10bd07de | 30 | __ASM volatile("nop\n"); |
wd5gnr | 0:8baa10bd07de | 31 | } |
wd5gnr | 0:8baa10bd07de | 32 | |
wd5gnr | 0:8baa10bd07de | 33 | |
wd5gnr | 0:8baa10bd07de | 34 | // Execution engines |
wd5gnr | 0:8baa10bd07de | 35 | |
wd5gnr | 0:8baa10bd07de | 36 | static void exec0() // timebase == 0.0, go as fast as possible |
wd5gnr | 0:8baa10bd07de | 37 | { |
wd5gnr | 0:8baa10bd07de | 38 | while (1) { |
wd5gnr | 0:8baa10bd07de | 39 | aout.write_u16(buffer[bp]); |
wd5gnr | 0:8baa10bd07de | 40 | bp=(bp+1)&BUFSIZEMASK; |
wd5gnr | 0:8baa10bd07de | 41 | } |
wd5gnr | 0:8baa10bd07de | 42 | } |
wd5gnr | 0:8baa10bd07de | 43 | |
wd5gnr | 0:8baa10bd07de | 44 | void exec() // All other time bases |
wd5gnr | 0:8baa10bd07de | 45 | { |
wd5gnr | 0:8baa10bd07de | 46 | unsigned i, newbase; |
wd5gnr | 0:8baa10bd07de | 47 | if (timebaseus==0) exec0(); // go as fast as possible -- never returns |
wd5gnr | 0:8baa10bd07de | 48 | #if CALIBRATE==1 |
wd5gnr | 0:8baa10bd07de | 49 | float m=1.0f,b=0.0f; |
wd5gnr | 0:8baa10bd07de | 50 | pc.printf("Using M=%f B=%f\r\n",m,b); |
wd5gnr | 0:8baa10bd07de | 51 | newbase=(unsigned int)((m*timebaseus-b)+0.5f); |
wd5gnr | 0:8baa10bd07de | 52 | #else |
wd5gnr | 0:8baa10bd07de | 53 | newbase=(unsigned int)((M*timebaseus-B)+0.5f); |
wd5gnr | 0:8baa10bd07de | 54 | #endif |
wd5gnr | 0:8baa10bd07de | 55 | while (1) { |
wd5gnr | 0:8baa10bd07de | 56 | aout.write_u16(buffer[bp]); |
wd5gnr | 0:8baa10bd07de | 57 | bp=(bp+1)&BUFSIZEMASK; |
wd5gnr | 0:8baa10bd07de | 58 | for (i=0; i<newbase; i++) { |
wd5gnr | 0:8baa10bd07de | 59 | nop(); // could shave a little off maybe by moving inline here |
wd5gnr | 0:8baa10bd07de | 60 | } |
wd5gnr | 0:8baa10bd07de | 61 | } |
wd5gnr | 0:8baa10bd07de | 62 | } |