Index: lab2/.idea/workspace.xml
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/xml
Index: lab2/lab2.c
===================================================================
--- lab2/lab2.c	(revision 3)
+++ lab2/lab2.c	(revision 4)
@@ -4,6 +4,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 
+extern unsigned int count;
 
 int main(int argc, char *argv[]) {
   // sets the language of LCF messages (can be either EN-US or PT-PT)
@@ -29,23 +30,74 @@
   return 0;
 }
 
+
 int(timer_test_read_config)(uint8_t timer, enum timer_status_field field) {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
 
-  return 1;
+  uint8_t st;
+
+  if(timer<0|timer>2){                      //tests for error in timer selection
+    printf("Error selecting timer\n");
+    return 1;
+  }
+  else if(timer_get_conf(timer, &st)==1){
+    printf("Error getting configuration\n");
+    return 1;
+  }
+  else if(timer_display_conf(timer, st, field)==1){
+    printf("Error getting display configuration\n");
+    return 1;
+  }
+  return 0;
 }
 
 int(timer_test_time_base)(uint8_t timer, uint32_t freq) {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
 
-  return 1;
+  if(timer_set_frequency(timer, freq)==1){                      //tests for error
+    printf("Error testing time base\n");
+    return 1;
+  }
+  return 0;
 }
 
 int(timer_test_int)(uint8_t time) {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
+  int r, ipc_status;
+  uint8_t irq_set;
+  message msg;
 
-  return 1;
+  if(timer_subscribe_int(&irq_set)==1){
+    printf("Error subscribing int\n");
+    return 1;
+  }
+
+  while(count/60.0<time){                                     //looping until counter reaches the same value as time
+    if ((r = driver_receive(ANY, &msg, &ipc_status))!=0){ 
+      printf("driver_receive failed with: %d",r);
+      continue;
+    }
+    if (is_ipc_notify(ipc_status)){                             //received notification
+      switch (_ENDPOINT_P(msg.m_source)){
+        case HARDWARE:                                          //hardware interrupt notification				
+                if (msg.m_notify.interrupts &irq_set){          // subscribed interrupt
+                  
+                  timer_int_handler();
+
+                  if((count%60)==0){
+                    timer_print_elapsed_time();                 //prints message each second;
+                  }
+                }
+               break;
+        default:
+              break;                                            //no other notifications expected: do nothing	
+        }
+    } 
+    else {                                                      //received a standard message, not a notification
+                                                                //no standard messages expected: do nothing
+    }
+  }
+  
+  if(timer_unsubscribe_int()==1){
+    printf("Error unsubscribing int\n");
+    return 1;
+  }
+  return 0;
 }
Index: lab2/timer.c
===================================================================
--- lab2/timer.c	(revision 3)
+++ lab2/timer.c	(revision 4)
@@ -5,43 +5,183 @@
 
 #include "i8254.h"
 
+unsigned int count=0; //Initializing counter
+int hook_id = TIMER0_IRQ;
+
 int (timer_set_frequency)(uint8_t timer, uint32_t freq) {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
+  // freq=TIMER_FREQ/div, where TIMER_FREQ is the frequency of the clock and div os the value loaded nittially in the timer
+    uint16_t div = (TIMER_FREQ /freq);
 
-  return 1;
+    uint8_t msb, lsb;
+
+    util_get_LSB(div,&lsb);         //getting LSB
+    util_get_MSB(div,&msb);         //getting MSB
+
+    uint8_t st;
+
+    if(timer_get_conf(timer,&st)!=0){
+        printf("Error getting conf in frequency set\n");
+        return 1;
+    }
+    if(timer<0|timer>2){
+        printf("Error selecting timer in frequency set\n");
+        return 1;
+    }
+    else
+    {
+        if(timer==0){
+            st= ((st & 0x0F)|TIMER_LSB_MSB|TIMER_SEL0);               //The mask 0x0f is used so that the 4 LSBs are not changed
+            sys_outb(TIMER_CTRL,st);                                //Sends control word to program the timer
+            sys_outb(TIMER_0,lsb);
+            sys_outb(TIMER_0,msb);                                  //Both these functions program the timer
+        }
+        else if(timer==1){
+            st= ((st & 0x0F)|TIMER_LSB_MSB|TIMER_SEL1); 
+            sys_outb(TIMER_CTRL,st);                   
+            sys_outb(TIMER_1,lsb);
+            sys_outb(TIMER_1,msb);
+        }
+        else if(timer==2){
+            st= ((st & 0x0F)|TIMER_LSB_MSB|TIMER_SEL2); 
+            sys_outb(TIMER_CTRL,st);                   
+            sys_outb(TIMER_2,lsb);
+            sys_outb(TIMER_2,msb);
+        }
+    }
+  return 0;
 }
 
 int (timer_subscribe_int)(uint8_t *bit_no) {
-    /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
-
-  return 1;
+    *bit_no = BIT(hook_id);
+    if(sys_irqsetpolicy(TIMER0_IRQ,IRQ_REENABLE,&hook_id)==1){      //operation to subscribe int
+        printf("Error subscribing int\n");
+        return 1;
+    }
+  return 0;
 }
 
 int (timer_unsubscribe_int)() {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
-
-  return 1;
+  if(sys_irqrmpolicy(&hook_id)==1){
+      printf("Error unsubscribing int\n");
+      return 1;
+  }
+  return 0;
 }
 
 void (timer_int_handler)() {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
+  count++;
 }
 
 int (timer_get_conf)(uint8_t timer, uint8_t *st) {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
 
-  return 1;
+    uint8_t read_back = TIMER_RB_CMD | TIMER_RB_COUNT_ | TIMER_RB_SEL(timer); //forming the read-back command (TIMER_RB_CMD (bit 7 and 6)
+                                                                                //TIMER_RB_COUNT (BIT 5) and TIMER_RB_SEL (bit timer+1)
+
+    if (sys_outb(TIMER_CTRL, read_back)!=1) {                            //testing for an error
+        switch (timer) {
+            case 0:
+                if (util_sys_inb(TIMER_0, st)!=0) {               //tests if TIMER_0 was chosen
+                    printf("Error selecting Timer 0\n");
+                    return 1;
+                }
+                break;
+            case 1:
+                if (util_sys_inb(TIMER_1, st)!=0) {               //tests if TIMER_1 was chosen
+                    printf("Error selecting Timer 1\n");
+                    return 1;
+                }
+                break;
+            case 2:
+                if (util_sys_inb(TIMER_2, st)!=0) {               //tests if TIMER_2 was chosen
+                    printf("Error selecting Timer 2\n");
+                    return 1;
+                }
+                break;
+            default:
+                printf("No clock selected\n");                                  //happens if timer<0 or timer>2
+                return 1;
+        }
+        return 0;
+    }
+    printf("Error in get config\n");
+    return 1;
 }
 
-int (timer_display_conf)(uint8_t timer, uint8_t st,
-                        enum timer_status_field field) {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
+int(timer_display_conf)(uint8_t timer, uint8_t st, enum timer_status_field field){
 
-  return 1;
+    if(timer < 0 | timer > 2)                           //tests if the timer has a correct value
+        return  1;
+
+    union timer_status_field_val config;                //create union (needed for the function at the end)
+    uint8_t aux;
+    aux=st;
+    switch(field){
+        case tsf_all:
+            config.byte=aux;
+            break;
+        case tsf_initial:                               //Checking init_mode (mask -> 0x30)
+            if((aux & 0x30)==TIMER_LSB){                //if 0x10
+                config.in_mode=LSB_only;
+            }
+            else if ((aux & 0x30)==TIMER_MSB){          //if 0x20
+                config.in_mode=MSB_only;
+            }
+            else if((aux & 0x30)==TIMER_LSB_MSB){       //if 0x30
+                config.in_mode=MSB_after_LSB;
+            }
+            else{
+                config.in_mode=INVAL_val;
+                printf("Invalid Initialization Mode\n");
+                return 1;
+            }
+            break;
+        case tsf_mode:                                  //Checking count_mode (mask -> 0x0E)
+            if((aux & 0x0E)==0){                        //if 0x00
+                config.count_mode=0;
+            }
+            else if((aux & 0x0E)==2){
+                config.count_mode=1;
+            }
+            else if((aux & 0x0E)==4|(aux & 0x0E)==12){
+                config.count_mode=2;
+            }
+            else if((aux & 0x0E)==6|(aux & 0x0E)==14){
+                config.count_mode=3;
+            }
+            else if((aux & 0x0E)==8){
+                config.count_mode=4;
+            }
+            else if((aux & 0x0E)==10){
+                config.count_mode=5;
+            }
+            else{
+                printf("Error in checking counting mode\n");
+                return 1;
+            }
+            break;
+        case tsf_base:                                  //Checking bcd (mask -> 0x01)
+            if((aux & 0x01)== TIMER_BCD){
+                config.bcd = true;                    //if the last bit is 1, it's bcd
+            }
+            else if((aux & 0x01)==TIMER_BIN){
+                config.bcd = false;                     //if the last bit is 0, it's binary
+            }
+            else{
+                printf("Error in checking base\n");
+                return 1;
+            }
+            break;
+        default:
+            return 1;
+
+    }
+
+    if(timer_print_config(timer, field, config)!=0){
+        printf("Error printing\n");
+        return 1;           //function that prints the result
+    }
+        
+
+    return 0;
+
 }
Index: lab2/utils.c
===================================================================
--- lab2/utils.c	(revision 3)
+++ lab2/utils.c	(revision 4)
@@ -3,22 +3,27 @@
 #include <stdint.h>
 
 int(util_get_LSB)(uint16_t val, uint8_t *lsb) {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
+  *lsb = (uint8_t) val;             //truncation of 16 bit to 8 bit (maintains the LSB)
 
-  return 1;
+  return 0;
 }
 
 int(util_get_MSB)(uint16_t val, uint8_t *msb) {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
+  val= val>>8;                      //8 bit shift, gets rid of LSB
+  *msb=(uint8_t)val;                //truncation of 16 bit to 8 bit (this time we have the MSB)
 
-  return 1;
+  return 0;
 }
 
-int (util_sys_inb)(int port, uint8_t *value) {
-  /* To be implemented by the students */
-  printf("%s is not yet implemented!\n", __func__);
+int (util_sys_inb)(int port, uint8_t *value) { //transform 8 bit into 32 bit
 
-  return 1;
+  uint32_t new_val;             //initializing 32 bit variable
+
+  if(sys_inb(port,&new_val)!=0){   //verifies if there is an error
+      printf("Error in util_sys_inb\n");
+      return 1;
+  }
+  *value=new_val & 0xFF;        // dereferencing "value"
+
+  return 0;
 }
