CIS441 Controller

Dependencies:   TextLCD mbed-rtos mbed

Fork of PacemakerController by Chad Nachiappan

PacemakerController.cpp

Committer:
lucastai
Date:
2015-11-30
Revision:
22:365d51eb3783
Parent:
18:d4cd9d12345e

File content as of revision 22:365d51eb3783:

#include "mbed.h"
#include "LPC17xx.h"
#include "TextLCD.h"
#include "rtos.h"
#include "Thread.h"
using namespace rtos;

 
// This is for the pacemaker
volatile unsigned short timer_count;
Serial pc(USBTX, USBRX);
TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x4); // rs, e, d4-d7

int keyboard_needs_numeric = 0; // boolean - is in middle of interval input?

int h_clock;
int pm_clock;
Timer avi_clock; 

int LRI = 1000;
int AVI = 150;
int PVARP = 300;
int VRP = 200;

// constants
int MAX_PM_RT = 180;
int MIN_PM_RT = 40;
enum mode {NORMAL, SLEEP, EXERCISE, MANUAL};

// counters
int beats = 0;

// state variables
int upper_bound = 100;
int lower_bound = 40;
int obs_int = 10;
mode curr_mode = NORMAL;

// alarms 
DigitalOut led_apace(LED1);
DigitalOut led_vpace(LED2);
DigitalOut Asense(LED3);
DigitalOut Vsense(LED4);

DigitalOut apace(p22):
DigitalOut vpace(p21):

// hardware interrupt handler, adapted from code in piazza post by Dagaen
extern "C" void TIMER0_IRQHandler (void)
{
if((LPC_TIM0->IR & 0x01) == 0x01)   // if MR0 interrupt, proceed
    {
    LPC_TIM0->IR |= 1 << 0;         // Clear MR0 interrupt flag
    timer_count++;                  //increment timer_count
    }
}
 
// init the hardware interrupt (timer0), adapted same as above
void timer0_init(void)
{
    LPC_SC->PCONP |=1<1;            //timer0 power on
    LPC_SC-> PCLKSEL0 |= 1 << 2;    // set timer clock to CCLCK nondivided (1 clock cycle = 1 increment)
    LPC_TIM0->MR0 = 1000000;          //100mhz clock cycle, 1 cycle = 10ns, 10ms = 10 000 000 ns = 1M cycles
    LPC_TIM0->MCR = 3;              //interrupt and reset control
                                    //3 = Interrupt & reset timer0 on match (111) sets all three bits
    NVIC_EnableIRQ(TIMER0_IRQn);    //enable timer0 interrupt
}


void PM_ALARM(void const *argument){
    
    // min hr alarm
    if( beats < MIN_PM_RT){
        lcd.locate(0,1);
        lcd.printf("!<"); 
    }
      
    // max hr alarm
    if(beats > MAX_PM_RT){
        lcd.locate(0,1);
        lcd.printf("!>"); 
    }  
    
}

// hw interrupt callback, deal with the keyboard input from PC
void keyboard_handler() {
    
    // get the char, put it on the PC command line
    char a = pc.getc();

    if (keyboard_needs_numeric) {
        if (a >= '0' && a <= '9') {
            // update observation interval
            obs_int = (a - '0' + 1) * 5;
        } else {
            pc.printf("Expected numeric key\n");    
        }
        keyboard_needs_numeric = 0;
    } else if(a == 'N'){
        // if the char is N, update bounds to normal mode
        curr_mode = NORMAL;
        upper_bound = 100;
        lower_bound = 40;
        pc.printf("MODE IS N\n");  
    // if the char is S, set bounds to sleep
    }else if (a == 'S'){
        curr_mode = SLEEP;
        upper_bound = 60;
        lower_bound = 30;
        pc.printf("MODE IS S\n");  
    // if the char is E, set bounds to exercise
    }else if (a == 'E'){
        curr_mode = EXERCISE;
        upper_bound = 175;
        lower_bound = 100;
        pc.printf("MODE IS E\n");  
        beats = 2;
    // if the char is M, set to manual
    }else if (a == 'M'){
        curr_mode = MANUAL;
        upper_bound = 175;
        lower_bound = 30;
        beats = 300;
        pc.printf("MODE IS MANUAL\n");  
    // check for A if mode is manual
    }else if (a == 'A'){
        if(curr_mode == MANUAL){
            pc.printf("MODE IS MANUAL GOT APACE\n");  
        }
    // check for V is mode is manual  
    }else if (a == 'V'){
        if(curr_mode == MANUAL){
            pc.printf("MODE IS MANUAL GOT VPACE\n");   
        }  
    }else if (a == 'O'){
        keyboard_needs_numeric = 1;
    } else{
        // do nothing for invalid char
    }
    
    keyboard_needs_number = 0; 
    
    
}

void pm_sense() {
    
    while(1) {
        
        if (timer_count >= VRP) {
              //wait for Vget;
              timer_count = 0;
              // do something with Vsense!
        } else if (timer_count < VRP) {
            // wait for Vget
        }
        
        if (timer_count < PVARP) {
            // wait for Aget?
        } else if (timer_count >= PVARP) {
            // wait for Aget?
            // do something with Asense!
        }
        
    }
}

void pm_response() {
 
    while(1) {
         if (timer_count >= LRI-AVI) {
             
             // PM_A! sets the LED high
             led_apace = 1;
             
             // avi_clk = 0
             avi_clk.reset();
             
             apace();
         } else if (timer_count < LRI - AVI) {
             
             // avi_clk = 0
             avi_clk.reset();
             
             // wait for Asense? naaah
         } 
         
         // At Atrial Event State
         while (avi_clk.read() < AVI);
         
         // Ventricular Event
         timer_count = 0;
         
         // PM_V! sets the LED high
         led_vpace = 1;
         
         timer_count = 0;
         vpace();
    } 
}


void apace() {
    
    apace = 1;
    led_apace = 1;
    Thread::wait(10);
    apace = 0;

}

void vpace() {
    
    vpace = 1;
    led_vpace = 1;
    Thread::wait(10);
    vpace = 0;
    
}


int main() {
    // https://developer.mbed.org/users/chadnach1/code/PacemakerController/
    // connect the serial device (PC keybd) to the interrupt
    pc.attach(&keyboard_handler);
    
    // Start LED's Off
    led_apace = 0;
    led_vpace = 0;
    
    // Start the avi_clock
    avi_clk.start();
    
    Thread t3(pm_sense);
    Thread t4(pm_response);

    Thread t2(PM_ALARM);
    Thread t5();

}