Project

General

Profile

Statistics
| Revision:

root / lab2 / timer.c @ 13

History | View | Annotate | Download (6.24 KB)

1
#include <lcom/lcf.h>
2
#include <lcom/timer.h>
3

    
4
#include <stdint.h>
5

    
6
#include "i8254.h"
7

    
8
unsigned int count=0; //Initializing counter
9
int hook_id = TIMER0_IRQ;
10

    
11
int (timer_set_frequency)(uint8_t timer, uint32_t freq) {
12

    
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
    uint16_t div = (TIMER_FREQ /freq);
19

    
20
    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
    if(timer_get_conf(timer,&st)==1){
28
        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
            st= ((st & 0x0F)|TIMER_LSB_MSB|TIMER_SEL0);             //The mask 0x0F is used so that the 4 LSBs are not changed
39
            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
}
58

    
59
int (timer_subscribe_int)(uint8_t *bit_no) {
60
    *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
}
67

    
68
int (timer_unsubscribe_int)() {
69
  if(sys_irqrmpolicy(&hook_id)==1){
70
      printf("Error unsubscribing int\n");
71
      return 1;
72
  }
73
  return 0;
74
}
75

    
76
void (timer_int_handler)() {
77
  count++;
78
}
79

    
80
int (timer_get_conf)(uint8_t timer, uint8_t *st) {
81

    
82
    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
                                                                                //TIMER_RB_COUNT (BIT 5) and TIMER_RB_SEL (bit timer+1)
84

    
85
    if (sys_outb(TIMER_CTRL, read_back)==0) {                            //testing for an error
86
        switch (timer) {
87
            case 0:
88
                if (util_sys_inb(TIMER_0, st)==1) {               //tests if TIMER_0 was chosen
89
                    printf("Error selecting Timer 0\n");
90
                    return 1;
91
                }
92
                break;
93
            case 1:
94
                if (util_sys_inb(TIMER_1, st)==1) {               //tests if TIMER_1 was chosen
95
                    printf("Error selecting Timer 1\n");
96
                    return 1;
97
                }
98
                break;
99
            case 2:
100
                if (util_sys_inb(TIMER_2, st)==1) {               //tests if TIMER_2 was chosen
101
                    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
    
112
    printf("Error in get config\n");
113
    return 1;
114
}
115

    
116
int(timer_display_conf)(uint8_t timer, uint8_t st, enum timer_status_field field){
117

    
118
    if(timer<0|timer>2){                                //tests for error in timer selection
119
        printf("Error selecting timer\n");
120
        return 1;
121
    }
122

    
123
    union timer_status_field_val config;                //create union (needed for the function at the end)
124
    uint8_t aux;
125
    aux=st;
126

    
127
    switch(field){
128
        case tsf_all:
129
            config.byte=aux;
130
            break;
131

    
132
        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

    
149
        case tsf_mode:                                  //Checking count_mode (mask -> 0x0E)
150
            if((aux & 0x0E)==0){                        //if 0x00
151
                config.count_mode=0;
152
            }
153
            else if((aux & 0x0E)==2){                   //if 0x02
154
                config.count_mode=1;
155
            }
156
            else if((aux & 0x0E)==4|(aux & 0x0E)==12){  //if 0x04 or 0x0C
157
                config.count_mode=2;
158
            }
159
            else if((aux & 0x0E)==6|(aux & 0x0E)==14){  //if 0x06 or 0x0E
160
                config.count_mode=3;
161
            }
162
            else if((aux & 0x0E)==8){                   //if 0x08
163
                config.count_mode=4;
164
            }
165
            else if((aux & 0x0E)==10){                  //if 0x0A
166
                config.count_mode=5;
167
            }
168
            else{
169
                printf("Error in checking counting mode\n");
170
                return 1;
171
            }
172
            break;
173

    
174
        case tsf_base:                                  //Checking bcd (mask -> 0x01)
175
            if((aux & 0x01)== TIMER_BCD){
176
                config.bcd = true;                      //if the last bit is 1, it's bcd
177
            }
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

    
187
        default:
188
            return 1;
189

    
190
    }
191

    
192
    if(timer_print_config(timer, field, config)==1){   //function that prints the result
193
        printf("Error printing\n");
194
        return 1;                                           
195
    }
196

    
197
    return 0;
198
}