coursework

Files at this revision

API Documentation at this revision

Comitter:
riyood
Date:
Sun Nov 27 17:57:06 2016 +0000
Commit message:
function;

Changed in this revision

generate.cpp Show annotated file Show diff for this revision Revisions of this file
interface.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
serial.cpp Show annotated file Show diff for this revision Revisions of this file
serial.h Show annotated file Show diff for this revision Revisions of this file
signal.cpp Show annotated file Show diff for this revision Revisions of this file
signal.h Show annotated file Show diff for this revision Revisions of this file
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", &amplitude))
+        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
+