coursework

Dependencies:   USBDevice mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
riyood
Date:
Mon Nov 28 10:32:43 2016 +0000
Commit message:
the coursework;

Changed in this revision

USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
function_generator/generate.cpp Show annotated file Show diff for this revision Revisions of this file
function_generator/interface.cpp Show annotated file Show diff for this revision Revisions of this file
function_generator/main.cpp Show annotated file Show diff for this revision Revisions of this file
function_generator/main.h Show annotated file Show diff for this revision Revisions of this file
function_generator/serial.cpp Show annotated file Show diff for this revision Revisions of this file
function_generator/serial.h Show annotated file Show diff for this revision Revisions of this file
function_generator/signal.cpp Show annotated file Show diff for this revision Revisions of this file
function_generator/signal.h Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice.lib	Mon Nov 28 10:32:43 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/USBDevice/#01321bd6ff89
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/function_generator/generate.cpp	Mon Nov 28 10:32:43 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;
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/function_generator/interface.cpp	Mon Nov 28 10:32:43 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");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/function_generator/main.cpp	Mon Nov 28 10:32:43 2016 +0000
@@ -0,0 +1,43 @@
+#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);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/function_generator/main.h	Mon Nov 28 10:32:43 2016 +0000
@@ -0,0 +1,11 @@
+#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);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/function_generator/serial.cpp	Mon Nov 28 10:32:43 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;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/function_generator/serial.h	Mon Nov 28 10:32:43 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/function_generator/signal.cpp	Mon Nov 28 10:32:43 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;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/function_generator/signal.h	Mon Nov 28 10:32:43 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 = 2,
+           float frequency = 10) :
+        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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Mon Nov 28 10:32:43 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/ST/code/mbed-rtos/#83895f30f8f2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Nov 28 10:32:43 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/d75b3fe1f5cb
\ No newline at end of file