local timers

Dependencies:   TextLCD mbed-rtos mbed

Fork of pacemaker_FINAL_v2 by Pacemaker

main.cpp

Committer:
jfields
Date:
2014-12-03
Revision:
1:ea01c3232c4a
Parent:
0:3afa00a23ce2
Child:
2:3773afd2256c

File content as of revision 1:ea01c3232c4a:

#include "mbed.h"
#include "rtos.h"
#include "TextLCD.h"
#include <stdio.h>
#include <stdlib.h>

#define RUN 0x1

TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD16x2);
Serial pc (USBTX, USBRX);

// ports
DigitalIn VGet(p11);
DigitalIn AGet(p12);
DigitalOut VPace(p13);
DigitalOut APace(p14);

// LEDs
DigitalOut leds[] = {LED1, LED2, LED3, LED4};
// 1 = VP
// 2 = AP
// 3 = VS
// 4 = AS

// global clocks
Timer ta;   // time since a event
Timer tv;   // time since v event

// mutexes
Mutex t_mutex;          // protect reading of ta, tv
Mutex status_mutex;     // protect reading of
Mutex input_mutex;      // protects reading input

// input stuff
char input;

// heart rate global vars
int HR = 0;
int beats = 0;
int sampleRate = 10000; // default 10 seconds
int firstSample = 1;

// Normal Values
const int N_PVARP = 325;    // ms
const int N_VRP   = 300;    // ms
const int N_LRI   = 857;    // ms (= about 70ppm)
const int N_AVI   = 65;     // ms
const int N_UB    = 100;    // 100ppm
const int N_LB    = 40;     // 40ppm

// Exercise Values
const int E_PVARP = 175;    // ms
const int E_VRP   = 150;    // ms
const int E_LRI   = 428;    // ms (= about 140ppm)
const int E_AVI   = 30;     // ms
const int E_UB    = 175;    // 175ppm
const int E_LB    = 100;    // 100ppm

// Sleep Values
const int S_PVARP = 500;    // ms
const int S_VRP   = 475;    // ms
const int S_LRI   = 1333;   // ms (= about 45ppm)
const int S_AVI   = 100;    // ms
const int S_UB    = 60;     // 60ppm
const int S_LB    = 30;     // 30ppm

// Heart Values - Normal Mode is default
int PVARP = N_PVARP;
int VRP = N_VRP;
int LRI = N_LRI;
int AVI = N_AVI;
int UB = N_UB;
int LB = N_LB;

// status flags
int isVRP = 0;
int isPVARP = 0;
int waitingForV = 1;

// functions
void VP_func(void const *args);
void AP_func(void const *args);
void VS_func(void const *args);
void AS_func(void const *args);
void manage_flags(void const *i);
void send_Apace();
void send_Vpace();
void listen_Aget(void const *args);
void listen_Vget(void const *args);
void flashLED(int i);
void blind();
void Aevent();
void calcHR(void const *args);
void disp(void const *args);
void input_func(void const *args);
void setVals(char c);

// threads
Thread * VS_thread;
Thread * AS_thread;
Thread * VP_thread;
Thread * AP_thread;
Thread * VG_thread;
Thread * AG_thread;
Thread * input_thread;
Thread * disp_thread;

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

int main() {
    
    // start global timer
    tv.start();
    ta.start();
    tv.stop();
    
    // init threads
    disp_thread = new Thread(disp);
    VS_thread = new Thread(VS_func);
    AS_thread = new Thread(AS_func);
    VP_thread = new Thread(VP_func);
    AP_thread = new Thread(AP_func);
    VG_thread = new Thread(listen_Vget);
    AG_thread = new Thread(listen_Aget);
    input_thread = new Thread(input_func);
    
    // 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);
    
    // main thread
    while (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');
        input_mutex.unlock();
    }
}

void calcHR(void const *args) {
    if (firstSample == 1) {
        HR = beats*(60000/sampleRate);
        firstSample = 0;
    }
    else {
        HR = (beats*60000/sampleRate+HR)/2;
    }
    disp_thread->signal_set(RUN);
}

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

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 AP_func(void const *args) {
    while (1) {
        t_mutex.lock();
        if (tv.read_ms() >= (LRI-AVI)) {
            Aevent();
            send_Apace();
            flashLED(2);
        }
        t_mutex.unlock();
    }
}

void VP_func(void const *args) {
    while (1) {
        t_mutex.lock();
        if (ta.read_ms() >= AVI) {
            blind();
            send_Vpace();
            flashLED(1);
        }
        t_mutex.unlock();
    }
}

void AS_func(void const *args) {
    while (1) {
        Thread::signal_wait(RUN,osWaitForever);
        t_mutex.lock();
        Aevent();
        flashLED(4);
        t_mutex.unlock();
    }
}

void VS_func(void const *args) {
    while (1) {
        Thread::signal_wait(RUN,osWaitForever);
        t_mutex.lock();
        blind();
        flashLED(3);
        t_mutex.unlock();
    }
}

void listen_Vget(void const *args) {
    while (1) {
        if (VGet==1) {
            status_mutex.lock();
            if (!isVRP && waitingForV) VS_thread->signal_set(RUN);
            status_mutex.unlock();
            while(VGet == 1);
        }
    }
}

void listen_Aget(void const *args) {
    while (1) {
        if (AGet == 1) {
            status_mutex.lock();
            if (!isPVARP && !waitingForV) AS_thread->signal_set(RUN);
            status_mutex.unlock();
            while(AGet == 1);
        }
    }
}

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

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

void Aevent() {
    ta.start();
    tv.reset();
    tv.stop();
    status_mutex.lock();
    waitingForV = 1;
    status_mutex.unlock();
}

void send_Apace() {
    APace = 1;
    Thread::wait(2);
    APace = 0;
}

void send_Vpace() {
    VPace = 1;
    Thread::wait(2);
    VPace = 0;
}

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;
    }
}