Project

General

Profile

Statistics
| Revision:

root / lab2 / timer.c @ 16

History | View | Annotate | Download (6.24 KB)

1 3 up20180645
#include <lcom/lcf.h>
2
#include <lcom/timer.h>
3
4
#include <stdint.h>
5
6
#include "i8254.h"
7
8 4 up20180645
unsigned int count=0; //Initializing counter
9
int hook_id = TIMER0_IRQ;
10
11 3 up20180645
int (timer_set_frequency)(uint8_t timer, uint32_t freq) {
12 5 up20180645
13
    if(freq<19){
14
        return 1;
15
    }
16
17
    //freq=TIMER_FREQ/div, where TIMER_FREQ is the frequency of the clock and div os the value loaded nittially in the timer
18 4 up20180645
    uint16_t div = (TIMER_FREQ /freq);
19 3 up20180645
20 4 up20180645
    uint8_t msb, lsb;
21
22
    util_get_LSB(div,&lsb);         //getting LSB
23
    util_get_MSB(div,&msb);         //getting MSB
24
25
    uint8_t st;
26
27 5 up20180645
    if(timer_get_conf(timer,&st)==1){
28 4 up20180645
        printf("Error getting conf in frequency set\n");
29
        return 1;
30
    }
31
    if(timer<0|timer>2){
32
        printf("Error selecting timer in frequency set\n");
33
        return 1;
34
    }
35
    else
36
    {
37
        if(timer==0){
38 5 up20180645
            st= ((st & 0x0F)|TIMER_LSB_MSB|TIMER_SEL0);             //The mask 0x0F is used so that the 4 LSBs are not changed
39 4 up20180645
            sys_outb(TIMER_CTRL,st);                                //Sends control word to program the timer
40
            sys_outb(TIMER_0,lsb);
41
            sys_outb(TIMER_0,msb);                                  //Both these functions program the timer
42
        }
43
        else if(timer==1){
44
            st= ((st & 0x0F)|TIMER_LSB_MSB|TIMER_SEL1);
45
            sys_outb(TIMER_CTRL,st);
46
            sys_outb(TIMER_1,lsb);
47
            sys_outb(TIMER_1,msb);
48
        }
49
        else if(timer==2){
50
            st= ((st & 0x0F)|TIMER_LSB_MSB|TIMER_SEL2);
51
            sys_outb(TIMER_CTRL,st);
52
            sys_outb(TIMER_2,lsb);
53
            sys_outb(TIMER_2,msb);
54
        }
55
    }
56
  return 0;
57 3 up20180645
}
58
59
int (timer_subscribe_int)(uint8_t *bit_no) {
60 4 up20180645
    *bit_no = BIT(hook_id);
61
    if(sys_irqsetpolicy(TIMER0_IRQ,IRQ_REENABLE,&hook_id)==1){      //operation to subscribe int
62
        printf("Error subscribing int\n");
63
        return 1;
64
    }
65
  return 0;
66 3 up20180645
}
67
68
int (timer_unsubscribe_int)() {
69 4 up20180645
  if(sys_irqrmpolicy(&hook_id)==1){
70
      printf("Error unsubscribing int\n");
71
      return 1;
72
  }
73
  return 0;
74 3 up20180645
}
75
76
void (timer_int_handler)() {
77 4 up20180645
  count++;
78 3 up20180645
}
79
80
int (timer_get_conf)(uint8_t timer, uint8_t *st) {
81
82 5 up20180645
    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)
83 4 up20180645
                                                                                //TIMER_RB_COUNT (BIT 5) and TIMER_RB_SEL (bit timer+1)
84
85 5 up20180645
    if (sys_outb(TIMER_CTRL, read_back)==0) {                            //testing for an error
86 4 up20180645
        switch (timer) {
87
            case 0:
88 5 up20180645
                if (util_sys_inb(TIMER_0, st)==1) {               //tests if TIMER_0 was chosen
89 4 up20180645
                    printf("Error selecting Timer 0\n");
90
                    return 1;
91
                }
92
                break;
93
            case 1:
94 5 up20180645
                if (util_sys_inb(TIMER_1, st)==1) {               //tests if TIMER_1 was chosen
95 4 up20180645
                    printf("Error selecting Timer 1\n");
96
                    return 1;
97
                }
98
                break;
99
            case 2:
100 5 up20180645
                if (util_sys_inb(TIMER_2, st)==1) {               //tests if TIMER_2 was chosen
101 4 up20180645
                    printf("Error selecting Timer 2\n");
102
                    return 1;
103
                }
104
                break;
105
            default:
106
                printf("No clock selected\n");                                  //happens if timer<0 or timer>2
107
                return 1;
108
        }
109
        return 0;
110
    }
111 5 up20180645
112 4 up20180645
    printf("Error in get config\n");
113
    return 1;
114 3 up20180645
}
115
116 4 up20180645
int(timer_display_conf)(uint8_t timer, uint8_t st, enum timer_status_field field){
117 3 up20180645
118 5 up20180645
    if(timer<0|timer>2){                                //tests for error in timer selection
119
        printf("Error selecting timer\n");
120
        return 1;
121
    }
122 4 up20180645
123
    union timer_status_field_val config;                //create union (needed for the function at the end)
124
    uint8_t aux;
125
    aux=st;
126 5 up20180645
127 4 up20180645
    switch(field){
128
        case tsf_all:
129
            config.byte=aux;
130
            break;
131 5 up20180645
132 4 up20180645
        case tsf_initial:                               //Checking init_mode (mask -> 0x30)
133
            if((aux & 0x30)==TIMER_LSB){                //if 0x10
134
                config.in_mode=LSB_only;
135
            }
136
            else if ((aux & 0x30)==TIMER_MSB){          //if 0x20
137
                config.in_mode=MSB_only;
138
            }
139
            else if((aux & 0x30)==TIMER_LSB_MSB){       //if 0x30
140
                config.in_mode=MSB_after_LSB;
141
            }
142
            else{
143
                config.in_mode=INVAL_val;
144
                printf("Invalid Initialization Mode\n");
145
                return 1;
146
            }
147
            break;
148 5 up20180645
149 4 up20180645
        case tsf_mode:                                  //Checking count_mode (mask -> 0x0E)
150
            if((aux & 0x0E)==0){                        //if 0x00
151
                config.count_mode=0;
152
            }
153 5 up20180645
            else if((aux & 0x0E)==2){                   //if 0x02
154 4 up20180645
                config.count_mode=1;
155
            }
156 5 up20180645
            else if((aux & 0x0E)==4|(aux & 0x0E)==12){  //if 0x04 or 0x0C
157 4 up20180645
                config.count_mode=2;
158
            }
159 5 up20180645
            else if((aux & 0x0E)==6|(aux & 0x0E)==14){  //if 0x06 or 0x0E
160 4 up20180645
                config.count_mode=3;
161
            }
162 5 up20180645
            else if((aux & 0x0E)==8){                   //if 0x08
163 4 up20180645
                config.count_mode=4;
164
            }
165 5 up20180645
            else if((aux & 0x0E)==10){                  //if 0x0A
166 4 up20180645
                config.count_mode=5;
167
            }
168
            else{
169
                printf("Error in checking counting mode\n");
170
                return 1;
171
            }
172
            break;
173 5 up20180645
174 4 up20180645
        case tsf_base:                                  //Checking bcd (mask -> 0x01)
175
            if((aux & 0x01)== TIMER_BCD){
176 5 up20180645
                config.bcd = true;                      //if the last bit is 1, it's bcd
177 4 up20180645
            }
178
            else if((aux & 0x01)==TIMER_BIN){
179
                config.bcd = false;                     //if the last bit is 0, it's binary
180
            }
181
            else{
182
                printf("Error in checking base\n");
183
                return 1;
184
            }
185
            break;
186 5 up20180645
187 4 up20180645
        default:
188
            return 1;
189
190
    }
191
192 5 up20180645
    if(timer_print_config(timer, field, config)==1){   //function that prints the result
193 4 up20180645
        printf("Error printing\n");
194 5 up20180645
        return 1;
195 4 up20180645
    }
196
197
    return 0;
198 3 up20180645
}