Yet another implementation of wave function generator
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /** mbed funcgen my implementation of a function generator 00002 * Copyright (c) 2014, 2015 Motoo Tanaka @ Design Methodology Lab 00003 * 00004 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00005 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00006 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00007 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00008 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00009 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00010 * THE SOFTWARE. 00011 */ 00012 00013 #include "mbed.h" 00014 #include "math.h" 00015 #include "vt100.h" 00016 00017 #if defined (TARGET_KL25Z) 00018 #define PIN_SCLK PTD1 00019 #define PIN_MISO PTD3 00020 #define PIN_MOSI PTD2 00021 #define PIN_CS_TFT PTD0 00022 #define PIN_DC_TFT PTD5 00023 #define PIN_CS_TSC PTA13 00024 #define PIN_BL_TFT PTC9 00025 #define PIN_CS_SD PTA4 00026 #define PIN_TSC_INTR PTC6 /* place holder */ 00027 #define PIN_RESET_TFT PTC5 /* place holder */ 00028 #define PIN_ADC_CH0 PTB0 00029 #define PIN_ADC_CH1 PTB2 00030 #define PIN_DAC_OUT PTE30 00031 00032 #elif defined (TARGET_KL46Z) 00033 #define PIN_SCLK PTD5 00034 #define PIN_MISO PTD7 00035 #define PIN_MOSI PTD6 00036 #define PIN_CS_TFT PTD4 00037 #define PIN_DC_TFT PTD2 00038 #define PIN_CS_TSC PTA13 00039 #define PIN_BL_TFT PTC9 00040 #define PIN_CS_SD PTA4 00041 #define PIN_TSC_INTR PTC7 /* place holder */ 00042 #define PIN_RESET_TFT PTC6 /* place holder */ 00043 #define PIN_ADC_CH0 PTB0 00044 #define PIN_ADC_CH1 PTB2 00045 #define PIN_DAC_OUT PTE30 00046 00047 #elif defined (TARGET_K64F) 00048 #define PIN_SCLK PTD1 00049 #define PIN_MISO PTD3 00050 #define PIN_MOSI PTD2 00051 #define PIN_CS_TFT PTD0 00052 #define PIN_DC_TFT PTC4 00053 // for board rev E or later 00054 #define PIN_CS_TSC PTC12 00055 // for earlier boards use following line 00056 // #define PIN_CS_TSC PTA0 00057 #define PIN_BL_TFT PTC3 00058 #define PIN_CS_SD PTB23 00059 #define PIN_TSC_INTR PTC0 /* place holder */ 00060 #define PIN_RESET_TFT PTC9 /* place holder */ 00061 #define PIN_ADC_CH0 PTB2 00062 #define PIN_ADC_CH1 PTB10 00063 #define PIN_DAC_OUT DAC0_OUT 00064 00065 #elif defined (TARGET_K22F) 00066 #define PIN_SCLK PTD5 00067 #define PIN_MISO PTD7 00068 #define PIN_MOSI PTD6 00069 #define PIN_CS_TFT PTD4 00070 #define PIN_DC_TFT PTA1 00071 #define PIN_CS_TSC PTB19 00072 #define PIN_BL_TFT PTC6 00073 #define PIN_CS_SD PTA4 00074 #define PIN_TSC_INTR PTC7 /* place holder */ 00075 #define PIN_RESET_TFT PTC9 /* place holder */ 00076 #define PIN_ADC_CH0 PTB0 00077 #define PIN_ADC_CH1 PTC1 00078 #define PIN_DAC_OUT DAC0_OUT 00079 00080 #elif defined (TARGET_NUCLEO_F411RE) 00081 #define PIN_SCLK PA_5 00082 #define PIN_MISO PA_6 00083 #define PIN_MOSI PA_7 00084 #define PIN_CS_TFT PB_6 00085 #define PIN_DC_TFT PC_7 00086 #define PIN_CS_TSC PA_9 00087 #define PIN_BL_TFT PA_8 00088 #define PIN_CS_SD PB_5 00089 #define PIN_TSC_INTR PA_8 /* place holder */ 00090 #define PIN_RESET_TFT PA_13 /* place holder */ 00091 #define PIN_ADC_CH0 PA_0 00092 #define PIN_ADC_CH1 PA_4 00093 00094 #else 00095 #error TARGET NOT DEFINED 00096 #define PIN_SCLK D13 00097 #define PIN_MISO D12 00098 #define PIN_MOSI D11 00099 #define PIN_CS_TFT D10 00100 #define PIN_DC_TFT D9 00101 #define PIN_CS_TSC D8 00102 #define PIN_BL_TFT D7 00103 #define PIN_CS_SD D4 00104 #define PIN_TSC_INTR NC 00105 #define PIN_RESET_TFT NC 00106 #define PIN_ADC_CH0 A0 00107 #define PIN_ADC_CH1 A2 00108 00109 #endif 00110 00111 #include "wave.h" 00112 #include "sinwave.h" 00113 #include "sqrwave.h" 00114 #include "sawwave.h" 00115 #include "triwave.h" 00116 00117 #define MODE_PAUSE 0x00 00118 #define MODE_RUN 0x01 00119 00120 #define MAX_WAVE 10 00121 00122 00123 00124 DigitalOut myled(LED1) ; 00125 AnalogOut aout(PIN_DAC_OUT) ; // SignalOut 00126 00127 Ticker *timer ; 00128 wave *wave_list[MAX_WAVE] ; 00129 wave *w = 0 ; 00130 int num_wave = 0 ; 00131 int wave_index = 0 ; 00132 bool ticked = false ; 00133 int vdout = 0 ; 00134 int avalue = 0 ; 00135 int aindex = 0 ; 00136 int mode = MODE_RUN ; 00137 vt100 *tty = 0 ; 00138 00139 /** usage display list of available commands 00140 */ 00141 void usage(void) 00142 { 00143 printf("=== funcgen (%s) ===\n\r", __DATE__) ; 00144 printf("run : start wave generation\n\r") ; 00145 printf("stop : stop wave generation\n\r") ; 00146 printf("help : print this help\n\r") ; 00147 printf("sin <amp> <freq> add a sine wave\n\r") ; 00148 printf("sqr <amp> <freq> <duty> add a square wave\n\r") ; 00149 printf("saw <amp> <freq> add a saw wave\n\r") ; 00150 printf("tri <amp> <freq> <duty> add a triangle wave\n\r") ; 00151 printf("------------------\n\r") ; 00152 printf("list (print list of waves)\n\r") ; 00153 printf("select <num> (select a target wave)\n\r") ; 00154 printf("delete (delete selected wave)\n\r") ; 00155 printf("amp <amp> (0 ~ 3.28 V)\n\r") ; 00156 printf("freq <freq> (0 ~ 12000 Hz)\n\r") ; 00157 printf("duty <duty> (0 ~ 100 %%)\n\r") ; 00158 printf("sample <time> (25~100 us(?))\n\r") ; 00159 printf("------------------\n\r") ; 00160 } 00161 00162 /** tick_time advance wave position(s) 00163 */ 00164 void tick_time(void) 00165 { 00166 int i ; 00167 int value = 0 ; 00168 for (i = 0 ; i < num_wave ; i++ ) { 00169 if (wave_list[i]) { 00170 value += wave_list[i]->value() ; 00171 wave_list[i]->advance() ; 00172 } 00173 } 00174 if (value > 0xFFFF) { // clip 00175 value = 0xFFFF ; 00176 } 00177 aout.write_u16(value) ; 00178 } 00179 00180 /** adjust sample time 00181 * For a single wave 25us seems to be sufficient 00182 * but adding more wave seems to require additional 00183 * 8us for each wave function. 00184 * These values are only from my experiments 00185 * so may be there is/are better numbers/solutions. 00186 */ 00187 void adjust_sample_time(int newvalue = 0) 00188 { 00189 int i ; 00190 if (timer) { 00191 timer->detach() ; 00192 } 00193 if (newvalue != 0) { 00194 sample_time = newvalue ; 00195 } else { 00196 sample_time = 17 + 8 * num_wave ; 00197 } 00198 for (i = 0 ; i < num_wave ; i++ ) { 00199 if (wave_list[i] != 0) { 00200 wave_list[i]->update() ; 00201 } 00202 } 00203 if (timer && (mode & MODE_RUN)) { 00204 timer->attach_us(&tick_time, sample_time) ; 00205 } 00206 } 00207 00208 void add_wave(wave *w) 00209 { 00210 if (num_wave < MAX_WAVE) { 00211 timer->detach() ; 00212 wave_index = num_wave ; 00213 wave_list[wave_index] = w ; 00214 num_wave++ ; 00215 adjust_sample_time() ; 00216 } else { 00217 printf("Maximum number of waves exceeded\n\r") ; 00218 } 00219 } 00220 00221 void delete_current_wave(void) 00222 { 00223 int i ; 00224 if (wave_list[wave_index] != 0) { 00225 timer->detach() ; 00226 delete wave_list[wave_index] ; 00227 for (i = wave_index ; i < num_wave ; i++ ) { 00228 wave_list[i] = wave_list[i+1] ; 00229 } 00230 num_wave-- ; 00231 wave_list[num_wave] = 0 ; 00232 if (wave_index >= num_wave) { 00233 wave_index = num_wave - 1 ; 00234 } 00235 w = wave_list[wave_index] ; 00236 adjust_sample_time() ; 00237 } 00238 } 00239 00240 void list_waves(void) 00241 { 00242 int i ; 00243 printf("sample time = %d(us) %d wave(s)\n\r", sample_time, num_wave) ; 00244 for (i = 0 ; i < num_wave ; i++ ) { 00245 if (i == wave_index) { 00246 printf("* ") ; 00247 } else { 00248 printf(" ") ; 00249 } 00250 printf("%d: ", i) ; 00251 if (wave_list[i]) { 00252 w = wave_list[i] ; 00253 printf("[ %s ] amp = %.2f V, freq = %d Hz, duty = %d %%", 00254 w->name(), w->volt(), w->freq(), w->duty()) ; 00255 } 00256 printf("\n\r") ; 00257 } 00258 w = wave_list[wave_index] ; 00259 } 00260 00261 /** main funcgen main program 00262 */ 00263 int main() { 00264 char cmd[32] ; 00265 int freq, duty ; 00266 float volt ; 00267 00268 tty = new vt100() ; 00269 tty->cls() ; 00270 usage() ; 00271 00272 timer = new Ticker() ; 00273 w = new sinwave(3.0, 1000, 0) ; 00274 add_wave(w) ; 00275 00276 timer->attach_us(&tick_time, sample_time) ; 00277 myled = 1 ; // turn the LED off 00278 00279 while(1) { 00280 printf("> ") ; 00281 scanf("%s", cmd) ; 00282 if (strcmp(cmd, "run") == 0) { // start timer 00283 mode |= MODE_RUN ; 00284 timer->attach_us(&tick_time, sample_time) ; 00285 } else if (strcmp(cmd, "stop") == 0) { // stop timer 00286 mode ^= MODE_RUN ; 00287 timer->detach() ; 00288 } else if (strcmp(cmd, "delete") == 0) { // delete current wave 00289 delete_current_wave() ; 00290 } else if (strcmp(cmd, "select") == 0) { // select a wave to be handled 00291 scanf("%d", &wave_index) ; 00292 if (wave_index >= num_wave) { 00293 wave_index = num_wave - 1; 00294 } 00295 w = wave_list[wave_index] ; 00296 } else if (strcmp(cmd, "sample") == 0) { // set time unit 00297 scanf("%d", &sample_time) ; 00298 adjust_sample_time(sample_time) ; 00299 } else if (strcmp(cmd, "sin") == 0) { // new sin wave 00300 scanf("%f %d", &volt, &freq) ; 00301 w = new sinwave(volt, freq) ; 00302 add_wave(w) ; 00303 } else if (strcmp(cmd, "sqr") == 0) { // new sqr wave 00304 scanf("%f %d %d", &volt, &freq, &duty) ; 00305 w = new sqrwave(volt, freq, duty) ; 00306 add_wave(w) ; 00307 } else if (strcmp(cmd, "saw") == 0) { // new saw wave 00308 scanf("%f %d", &volt, &freq) ; 00309 w = new sawwave(volt, freq) ; 00310 add_wave(w) ; 00311 } else if (strcmp(cmd, "tri") == 0) { // new tri wave 00312 scanf("%f %d %d", &volt, &freq, &duty) ; 00313 w = new triwave(volt, freq, duty) ; 00314 add_wave(w) ; 00315 } else if (strcmp(cmd, "amp") == 0) { 00316 scanf("%f", &volt) ; 00317 if (w != 0) { 00318 w->volt(volt) ; 00319 } 00320 } else if (strcmp(cmd, "freq") == 0) { 00321 scanf("%d", &freq) ; 00322 if (w != 0) { 00323 w->freq(freq) ; 00324 } 00325 } else if (strcmp(cmd, "duty") == 0) { 00326 scanf("%d", &duty) ; 00327 if (w != 0) { 00328 w->duty(duty) ; 00329 } 00330 } else if (strcmp(cmd, "list") == 0) { 00331 list_waves() ; 00332 } else if (strcmp(cmd, "help") == 0) { 00333 usage() ; 00334 } else { 00335 usage() ; 00336 } 00337 } 00338 }
Generated on Wed Jul 13 2022 01:58:56 by
1.7.2