Penn CIS 441/541 Assignment. Fall 2015

Dependencies:   TextLCD mbed

Revision:
0:068ad2e1c21d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Oct 11 18:21:22 2015 +0000
@@ -0,0 +1,197 @@
+#include "mbed.h"
+#include "LPC17xx.h"
+#include "TextLCD.h"
+ 
+// declare hardware you're going to use, mostly copied from example code in previous assignments / Dagens piazza post
+volatile unsigned short timer_count;
+Serial pc(USBTX, USBRX);
+TextLCD lcd(p15, p16, p17, p18, p19, p20, TextLCD::LCD20x4); // rs, e, d4-d7
+
+// declare constants used for counting
+int running = 0;
+char mins_tens = '0';
+char mins_ones = '0';
+char seconds_tens = '0';
+char seconds_ones = '0';
+char ms_tens = '0';
+char ms_ones = '0';
+
+
+// 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
+}
+
+// update the display with the global timer values
+void update_display(void){
+     // initialize the display, start at 0, paused
+    // first MM
+    lcd.locate(0,0);
+    lcd.putc(mins_tens);
+    lcd.locate(1,0);
+    lcd.putc(mins_ones);
+    // then : 
+    lcd.locate(2,0);
+    lcd.putc(':');
+    // then SS
+    lcd.locate(3,0);
+    lcd.putc(seconds_tens);
+    lcd.locate(4,0);
+    lcd.putc(seconds_ones);
+    // then :
+    lcd.locate(5,0);
+    lcd.putc(':');
+    // then mS
+    lcd.locate(6,0);
+    lcd.putc(ms_tens);
+    lcd.locate(7,0);
+    lcd.putc(ms_ones);
+}
+
+// reset global values to 0
+void reset(void){
+    mins_tens = '0';
+    mins_ones = '0';
+    seconds_tens = '0';
+    seconds_ones = '0';
+    ms_tens = '0';
+    ms_ones = '0';
+}
+
+// hw interrupt callback, deal with the keyboard input from PC
+void kb_interrupt() {
+    
+    // get the char, put it on the PC command line
+    char a = pc.getc();
+    pc.putc(a);
+    // if the char is S, make sure TCR's relevant bit is set
+    if(a == 's'){
+        // start timer
+        running = 1;
+        LPC_TIM0->TCR |= 1 << 0;
+    // if the char is p, clear TCR, pausing the timer
+    }else if (a == 'p'){
+        LPC_TIM0->TCR = 0;
+        running = 0;
+    // if the char is r, reset the timer, potentially update display independent of clk interrupt if stopped
+    }else if (a == 'r'){
+        reset();
+        if(!running){
+            update_display();
+        }
+    }else{
+        // do nothing for invalid char
+    }
+}
+
+ 
+int main (void) 
+{
+    
+    // connect the serial device (PC keybd) to the interrupt
+    pc.attach(&kb_interrupt);
+    
+    // reset the counters, display the original 00:00:00 state
+    reset();
+    update_display();
+    
+    
+    //init vars, start timer
+    timer_count = 0;
+    timer0_init();
+    
+    // main program loop
+    while(true){
+        // on 10ms interrupt
+        if(timer_count){
+            // set timer count to 0 every 10ms
+            timer_count = 0;
+            
+            // count up on 10ms interrupt, make sure counter updates properly
+            
+            // update ms ones
+            int msones_carry_flag = 0;
+            if(ms_ones == '9'){
+                ms_ones = '0';
+                msones_carry_flag = 1;
+            }else{
+                ms_ones++;
+            }
+            
+            // update ms tens
+            int mstens_carry_flag = 0;
+            if(msones_carry_flag){
+                if(ms_tens == '9'){
+                    ms_tens = '0';
+                    mstens_carry_flag = 1;
+                }else{
+                    ms_tens++;
+                } 
+            }
+            
+            // update sec ones
+            int seconds_ones_carry_flag = 0;
+            if(mstens_carry_flag){
+                if(seconds_ones == '9'){
+                    seconds_ones = '0';
+                    seconds_ones_carry_flag = 1;
+                }else{
+                    seconds_ones++;
+                } 
+            }
+            
+            // update sec tens
+            int seconds_tens_carry_flag = 0;
+            if(seconds_ones_carry_flag){
+                if(seconds_tens == '5'){
+                    seconds_tens = '0';
+                    seconds_tens_carry_flag = 1;
+                }else{
+                    seconds_tens++;
+                } 
+            }
+            
+            // update mins ones
+            int mins_ones_carry_flag = 0;
+            if(seconds_tens_carry_flag){
+                if(mins_ones == '9'){
+                    mins_ones = '0';
+                    mins_ones_carry_flag = 1;
+                }else{
+                    mins_ones++;
+                } 
+            }
+            
+            // update mins tens
+            if(mins_ones_carry_flag){
+                if(mins_ones == '9'){
+                    mins_ones = '0';
+                    mins_ones_carry_flag = 1;
+                }else{
+                    mins_ones++;
+                } 
+            }
+            
+            // update display with new vals
+            update_display();
+        
+        }
+
+    }   
+}
\ No newline at end of file