local timers

Dependencies:   TextLCD mbed-rtos mbed

Fork of pacemaker_FINAL_v1 by Pacemaker

main.cpp

Committer:
jfields
Date:
2014-12-04
Revision:
6:704de3abb5e9
Parent:
5:8cd62e3c3c3a

File content as of revision 6:704de3abb5e9:

#include "constants.h"

// global timer
Timer tv;
Timer ta;

// mutexes
Mutex t_mutex;          // protect reading of ta, tv
Mutex status_mutex;     // protect reading of
Mutex input_mutex;      // protects reading input
Mutex man_mutex;        // protects manual
Mutex state_mutex;      // protects waitingForV

// functions
void A_func(void const *args);
void V_func(void const *args);
void manage_flags(void const *i);
void flashLED(int i);
void calcHR(void const *args);
void disp(void const *args);
void input_func(void const *args);
void setVals(char c);
void makeManual();
void blind();
void get_listener(void const *args);
void updateSR();

// threads
Thread * A_thread;
Thread * V_thread;
Thread * input_thread;
Thread * disp_thread;
Thread * listener;

// rtos timers
RtosTimer * VRP_timer;
RtosTimer * PVARP_timer;
RtosTimer * HR_timer;

int main() {
    
    // init threads
    disp_thread = new Thread(disp);
    input_thread = new Thread(input_func);
    A_thread = new Thread(A_func);
    V_thread = new Thread(V_func);
    listener = new Thread(get_listener);
    
    // init timers
    VRP_timer = new RtosTimer(manage_flags, osTimerOnce, (void *)1);
    PVARP_timer = new RtosTimer(manage_flags, osTimerOnce, (void *)2);
    HR_timer = new RtosTimer(calcHR, osTimerPeriodic, (void *)0);
    
    // start display and heart rate sample
    HR_timer->start(sampleRate);
    disp_thread->signal_set(RUN);
    
    // start pacemaker
    ta.start();
    tv.start();
    V_thread->signal_set(RUN);
    
    // main thread
    while (1) {
        
    }
}

void A_func(void const *args) {
    while (1) {
        Thread::signal_wait(RUN, osWaitForever);
        int done = 0;
        while (!done) {
            if (ta.read_ms() >= LRI-AVI) {
                tv.reset();
                V_thread->signal_set(RUN);
                APace = 1;
                Thread::wait(2);
                APace = 0;
                flashLED(2);
                done = 1;
            }
            if (AGet == 1 && !isPVARP) {
                tv.reset();
                V_thread->signal_set(RUN);
                flashLED(4);
                done = 1;
            }
        }
    }
}

void V_func(void const *args) {
    while (1) {
        Thread::signal_wait(RUN, osWaitForever);
        int done = 0;
        while (!done) {
            if (tv.read_ms() >= AVI) {
                ta.reset();
                A_thread->signal_set(RUN);
                VPace = 1;
                Thread::wait(2);
                VPace = 0;
                blind();
                flashLED(1);
                done = 1;
            }
            if (VGet == 1 && !isVRP) {
                ta.reset();
                A_thread->signal_set(RUN);
                blind();
                flashLED(3);
                done = 1;
            }
        }
    }
}

void input_func(void const *args) {
    while (1) {
        input_mutex.lock();
        input=pc.getc();
        if (input == 'n') setVals('n');
        if (input == 's') setVals('s');
        if (input == 'e') setVals('e');
        if (input == 'm') makeManual();
        if (input == 'o') {
            lcd.printf("Enter\n\n");
            Omode = 1;
            input = pc.getc();
            if (input == '1') {
                sampleRate = 10000;
                updateSR();
            }
            if (input == '2') {
                sampleRate = 20000;
                updateSR();
            }
            if (input == '3') {
                sampleRate = 30000;
                updateSR();
            }
            if (input == '4') {
                sampleRate = 60000;
                updateSR();
            }
            if (input == '5') {
                sampleRate = 100000;
                updateSR();
            }
        }
        input_mutex.unlock();
    }
}

void calcHR(void const *args) {
    status_mutex.lock();
    if (firstSample == 1) {
        HR = beats*(60000/sampleRate);
        firstSample = 0;
    }
    else {
        HR = (beats*60000/sampleRate+HR)/2;
    }
    if (HR>=UB || HR<=LB) {
        speaker.period(1.0/500.0); // 500hz period
        speaker =0.5;
    }
    else {
        speaker=0.0;
    }
    status_mutex.unlock();
    disp_thread->signal_set(RUN);
}

void disp(void const *args) {
    while (1) {
        Thread::signal_wait(RUN,osWaitForever);
        status_mutex.lock();
        if (!Omode) {
            lcd.printf("HR = %d ppm\nCycle = %d s\n",HR,sampleRate/1000);
        }
        beats = 0;
        status_mutex.unlock();
    }
}

void manage_flags(void const *i) {
    status_mutex.lock();
    if ((int)i==1) isVRP = 0;
    if ((int)i==2) isPVARP = 0;
    status_mutex.unlock();
}

void flashLED(int i) {
    leds[i-1] = 1;
    wait(0.01);
    leds[i-1] = 0;
}

void blind() {
    status_mutex.lock();
    isVRP = 1;
    isPVARP = 1;
    VRP_timer->start(VRP);
    PVARP_timer->start(PVARP);
    beats++;
    status_mutex.unlock();
}

void makeManual() {
    man_mutex.lock();
    inManual = 1;
    man_mutex.unlock();
    UB = 175;
    LB = 30;
    int done = 0;
    while (!done) {
        input = pc.getc();
        if (input == 'v') {
            VPace = 1;
            Thread::wait(2);
            VPace = 0;
            flashLED(1);
        }
        if (input == 'a') {
            APace = 1;
            Thread::wait(2);
            APace = 0;
            flashLED(2);
        }
        if (input == 's') {
            setVals('s');
            done = 1;
        }
        if (input == 'e') {
            setVals('s');
            done = 1;
        }
        if (input == 'n') {
            setVals('s');
            done = 1;
        }
        if (input == 'o') {
            lcd.printf("Enter\n\n");
            Omode = 1;
            input = pc.getc();
            if (input == '1') {
                sampleRate = 10000;
                updateSR();
            }
            if (input == '2') {
                sampleRate = 20000;
                updateSR();
            }
            if (input == '3') {
                sampleRate = 30000;
                updateSR();
            }
            if (input == '4') {
                sampleRate = 60000;
                updateSR();
            }
            if (input == '5') {
                sampleRate = 100000;
                updateSR();
            }
        }
    }
    VRP_timer->stop();
    PVARP_timer->stop();
    man_mutex.lock();
    inManual = 0;
    man_mutex.unlock();
}

void get_listener(void const *args) {
    while (1) {
        if (inManual) {
            if (AGet == 1) {
                flashLED(4);
                while (AGet == 1);
            }
            if (VGet == 1) {
                flashLED(3);
                while (VGet == 1);
            }
        }
    }
}

void setVals(char c) {
    if (c == 'n') {
        PVARP = N_PVARP;
        VRP = N_VRP;
        LRI = N_LRI;
        AVI = N_AVI;
        UB = N_UB;
        LB = N_LB;
    }
    if (c == 's') {
        PVARP = S_PVARP;
        VRP = S_VRP;
        LRI = S_LRI;
        AVI = S_AVI;
        UB = S_UB;
        LB = S_LB;
    }
    if (c == 'e') {
        PVARP = E_PVARP;
        VRP = E_VRP;
        LRI = E_LRI;
        AVI = E_AVI;
        UB = E_UB;
        LB = E_LB;
    }
}

void updateSR() {
    status_mutex.lock();
    beats = 0;
    HR = 0;
    Omode = 0;
    firstSample = 1;
    HR_timer->stop();
    HR_timer->start(sampleRate);
    status_mutex.unlock();
    disp_thread->signal_set(RUN);
}