coursework
Revision 0:b7287557047e, committed 2016-11-27
- Comitter:
- riyood
- Date:
- Sun Nov 27 17:57:06 2016 +0000
- Commit message:
- function;
Changed in this revision
diff -r 000000000000 -r b7287557047e generate.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/generate.cpp Sun Nov 27 17:57:06 2016 +0000 @@ -0,0 +1,60 @@ +#include "main.h" +#include "rtos.h" + +DigitalOut greenLed (PD_12); +DigitalOut orangeLed (PD_13); +DigitalOut redLed (PD_14); +DigitalOut blueLed (PD_15); + +AnalogOut *aout; +Timer timer; +const float pi = 3.141592653589793238462f; + + +//Mutex signalMutex; +bool signalHasChanged; +Signal signalToGenerate; + +void updateSignal (Signal signal) { + //signalMutex.lock(); // synchronise access with generateSignalFunc() + signalToGenerate = signal; // specify that the signal + signalHasChanged = 1; // to generate has changed + //signalMutex.unlock(); +} + + +void generateSignalFunc (void const* args) { + enum SIGNAL_TYPE type; + float a, f, p, t; + timer.start(); + + while(1) { + if(signalHasChanged) { + //signalMutex.lock(); // prevent changes to occur while + type = signalToGenerate.type; // signal parameters are being read + a = signalToGenerate.amplitude/3.3f; // scale from [0,3.3] to [0,1] + f = signalToGenerate.frequency; + signalHasChanged = 0; // reset flag + //signalMutex.unlock(); // release lock + greenLed = type==CONSTANT; + orangeLed = type==SINE; + redLed = type==SQUARE; + } + t = timer.read(); // get time t in seconds + if(t>20) timer.reset(); // accuracy drops as t increases + switch(type) { + case CONSTANT: + *aout = a; + break; + case SINE: + *aout = a*0.5f*(1+sin(f*pi*2*t)); + break; + case SQUARE: + p = t*f - floor(t*f); + *aout = (p < 0.5f) ? 0 : a; + break; + default: *aout = 0; + } + } +} +
diff -r 000000000000 -r b7287557047e interface.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interface.cpp Sun Nov 27 17:57:06 2016 +0000 @@ -0,0 +1,99 @@ +#include "main.h" +#include "rtos.h" +#include <vector> +#include <algorithm> + +std::vector<Signal> recall; + + +bool get_amplitude (float & amplitude) { + if(!serial.scanf("%f", &litude)) + serial.puts("Invalid amplitude!\r\n"); + else if(!(0 <= amplitude && amplitude <= 3.3f)) + serial.puts("Amplitude not in range [0, 3.3].\r\n"); + else return 1; + return 0; +} + +bool get_frequency (float & frequency) { + if(!serial.scanf("%f", &frequency)) + serial.puts("Invalid frequency!\r\n"); + else if(!(0 <= frequency && frequency <= 100000)) + serial.puts("Frequency not in range [0, 100000].\r\n"); + else return 1; + return 0; +} + + +osThreadId mainThreadId; + +void callback_on_input() { + // inform mainThread that there is user input + osSignalSet(mainThreadId, 0x1); + //Thread::wait(1000); // wait 1s +} + +void userInterfaceFunc (void const* args) { + mainThreadId = Thread::gettid(); + serial.attach(&callback_on_input); + while(1) { + serial.puts("\r\n"); + serial.puts("Enter signal to generate, in the form:\r\n"); + serial.puts(" * constant <amplitude>\r\n"); + serial.puts(" * sine <amplitude> <frequency>\r\n"); + serial.puts(" * square <amplitude> <frequency>\r\n"); + serial.puts(" * recall <index>\r\n"); + serial.puts(" * clear\r\n"); + + char* str = buffer; + Signal signal; + + while(1) { + serial.puts("Choice: "); + serial.flush(); + + osSignalClear(mainThreadId, 0x1); // ensure thread_signal is cleared + Thread::signal_wait(0x1); // now wait for that thread_signal + serial.scanf("%s", str); // then get the available user input + + if(0==strcmp(str, "constant")) { + signal.frequency = 0; + if(get_amplitude(signal.amplitude)) + { signal.type = CONSTANT; break; } + } + else if(0==strcmp(str, "sine")) { + if(get_amplitude(signal.amplitude) + && get_frequency(signal.frequency)) + { signal.type = SINE; break; } + } + else if(0==strcmp(str, "square")) { + if(get_amplitude(signal.amplitude) + && get_frequency(signal.frequency)) + { signal.type = SQUARE; break; } + } + else if(0==strcmp(str, "recall")) { + int i, max = recall.size()-1; + if(!serial.scanf("%d", &i)) + serial.puts("Invalid index!\r\n"); + else if(i<0 || i>max) + serial.printf("Index not in range [0, %d].\r\n", max); + else { signal = recall[i]; break; } + } + else if(0==strcmp(str, "clear")) { + recall.clear(); + serial.puts("Done.\r\n"); + } + else serial.puts("Invalid command!\r\n"); + } + serial.printf("Done: %s.\r\n", signal.c_str(buffer)); + + if(std::find(recall.begin(), recall.end(), signal) == recall.end()) // if signal does not already exists + { + serial.printf("Index of signal is %d.\r\n", recall.size()); // then add the new signal + recall.push_back(signal); // and provide its index + } + updateSignal(signal); + serial.puts("----------------------\r\n"); + } +} +
diff -r 000000000000 -r b7287557047e main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Nov 27 17:57:06 2016 +0000 @@ -0,0 +1,44 @@ +#include "mbed.h" +#include "main.h" +#include "rtos.h" + + +void get_which_dac_to_use() { + int dac = 1; + while(1) { + serial.puts("\r\n"); + serial.puts("Select which DAC to use:\r\n"); + serial.puts(" 1 : DAC 1 (PA_4)\r\n"); + serial.puts(" 2 : DAC 2 (PA_5)\r\n"); + serial.puts("Choice: "); + serial.flush(); + serial.gets(buffer, BUFFER_SIZE); + char* str = buffer; + if(0==strcmp(str, "1")) { dac=1; break; } + if(0==strcmp(str, "2")) { dac=2; break; } + serial.puts("Invalid selection!\r\n"); + } + if(dac==1) aout = new AnalogOut(PA_4); + if(dac==2) aout = new AnalogOut(PA_5); + serial.printf("Done: %d.\r\n", dac); +} + + +void get_serial_port_ready() { + for(int i=10; i>0; i--) { + serial.printf("Wait %ds\r\n", i*2); + wait(2); + } + serial.puts("***************************************\r\n"); + serial.puts("*** Welcome to my Signal Generator! ***\r\n"); + serial.puts("***************************************\r\n"); +} + + +int main() { + get_serial_port_ready(); + get_which_dac_to_use(); + Thread generateSignal(generateSignalFunc); + userInterfaceFunc(NULL); +} +
diff -r 000000000000 -r b7287557047e main.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.h Sun Nov 27 17:57:06 2016 +0000 @@ -0,0 +1,12 @@ + +#include "serial.h" +#include "signal.h" + +/* defined in generate.cpp */ +extern AnalogOut *aout; +extern void updateSignal (Signal signal); +extern void generateSignalFunc (void const* args); + +/* defined in interface.cpp */ +extern void userInterfaceFunc (void const* args); +
diff -r 000000000000 -r b7287557047e serial.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/serial.cpp Sun Nov 27 17:57:06 2016 +0000 @@ -0,0 +1,24 @@ +#include "serial.h" + +char* buffer = new char[BUFFER_SIZE]; + +USB_Serial serial; + +void USB_Serial::flush() { + while(serial.readable()) + serial.getc(); +} + +int USB_Serial::gets (char* str, int size) { + int i=0; + char c; + while(1) { + c = serial.getc(); + if(c=='\r' || c=='\n') break; + str[i++] = c; + if(i+1==size) break; + } + str[i]=0; + return i; +} +
diff -r 000000000000 -r b7287557047e serial.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/serial.h Sun Nov 27 17:57:06 2016 +0000 @@ -0,0 +1,22 @@ +#ifndef _SERIAL_H +#define _SERIAL_H + +#include "mbed.h" +#include "USBSerial.h" + +// Virtual serial port over USB +class USB_Serial : public USBSerial { +public: + void flush(); + + /* It seems original gets() does not work, + probably due to the newline character. */ + int gets (char* str, int size); +}; + +extern USB_Serial serial; + +#define BUFFER_SIZE 1000 +extern char* buffer; + +#endif
diff -r 000000000000 -r b7287557047e signal.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/signal.cpp Sun Nov 27 17:57:06 2016 +0000 @@ -0,0 +1,13 @@ +#include "signal.h" +#include "stdio.h" // for sprintf() + +const char* Signal::c_str (char* str) { + switch(type){ + case CONSTANT: sprintf(str, "constant %f", amplitude); break; + case SINE: sprintf(str, "sin %f %f", amplitude, frequency); break; + case SQUARE: sprintf(str, "square %f %f", amplitude, frequency); break; + default: sprintf(str, "none"); break; + } + return str; +} +
diff -r 000000000000 -r b7287557047e signal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/signal.h Sun Nov 27 17:57:06 2016 +0000 @@ -0,0 +1,32 @@ +#ifndef _SIGNAL_H +#define _SIGNAL_H + +enum SIGNAL_TYPE { + NONE, + CONSTANT, + SINE, + SQUARE +}; + +class Signal { +public: + enum SIGNAL_TYPE type; + float amplitude; + float frequency; + + Signal(enum SIGNAL_TYPE type = NONE, + float amplitude = 0, + float frequency = 0) : + type(type), amplitude(amplitude), frequency(frequency) {} + + void set(enum SIGNAL_TYPE _type, float _amplitude, float _frequency) { + type=_type; amplitude=_amplitude; frequency=_frequency; } + + bool operator== (const Signal & s) { + return type==s.type && amplitude==s.amplitude && frequency==s.frequency; } + + const char* c_str (char* str); +}; + +#endif +