root / lab3 / lab3.c @ 8
History | View | Annotate | Download (7.23 KB)
1 | 4 | up20180614 | #include <lcom/lcf.h> |
---|---|---|---|
2 | #include <minix/sysutil.h> |
||
3 | |||
4 | #include <lcom/lab3.h> |
||
5 | |||
6 | #include <stdbool.h> |
||
7 | 8 | up20180614 | #include "i8254.h" |
8 | 4 | up20180614 | #include <stdint.h> |
9 | //#include <timer.c>
|
||
10 | |||
11 | 7 | up20180614 | |
12 | 4 | up20180614 | #define IRQ_KB 1 |
13 | #define DELAY_US 20000 |
||
14 | #define EXIT_CODE 0x81 |
||
15 | #define I_O_BUFFER 0x60 |
||
16 | |||
17 | static uint32_t scancode;
|
||
18 | |||
19 | int main(int argc, char *argv[]) { |
||
20 | // sets the language of LCF messages (can be either EN-US or PT-PT)
|
||
21 | lcf_set_language("EN-US");
|
||
22 | |||
23 | // enables to log function invocations that are being "wrapped" by LCF
|
||
24 | // [comment this out if you don't want/need it]
|
||
25 | lcf_trace_calls("/home/lcom/labs/lab3/trace.txt");
|
||
26 | |||
27 | // enables to save the output of printf function calls on a file
|
||
28 | // [comment this out if you don't want/need it]
|
||
29 | lcf_log_output("/home/lcom/labs/lab3/output.txt");
|
||
30 | |||
31 | // handles control over to LCF
|
||
32 | // [LCF handles command line arguments and invokes the right function]
|
||
33 | if (lcf_start(argc, argv))
|
||
34 | 6 | up20180614 | return 1; |
35 | 4 | up20180614 | |
36 | // LCF clean up tasks
|
||
37 | // [must be the last statement before return]
|
||
38 | lcf_cleanup(); |
||
39 | |||
40 | return 0; |
||
41 | } |
||
42 | |||
43 | 5 | up20180614 | void(kbc_ih)() {}
|
44 | 4 | up20180614 | |
45 | int(kbd_test_scan)() {
|
||
46 | /* To be completed by the students */
|
||
47 | int ipc_status;
|
||
48 | 5 | up20180614 | uint8_t r, bit_no = 0;
|
49 | 4 | up20180614 | message msg; |
50 | 5 | up20180614 | int hook_id = bit_no;
|
51 | uint8_t scan_arr[2] = {0, 0}; |
||
52 | 8 | up20180614 | |
53 | 6 | up20180614 | int flag = 0; |
54 | 7 | up20180614 | uint32_t cnt=0;
|
55 | 4 | up20180614 | |
56 | 5 | up20180614 | printf("%d\n",
|
57 | sys_irqsetpolicy(IRQ_KB, IRQ_REENABLE | IRQ_EXCLUSIVE, &hook_id)); |
||
58 | /* sys_outb(0x64, 0x20);
|
||
59 | sys_inb(0x64, &scancode);
|
||
60 | printf("%x\n", scancode);
|
||
61 | if (scancode & 0x10) {
|
||
62 | scancode = (scancode & 0xEF);
|
||
63 | }
|
||
64 | |||
65 | printf("%x\n", scancode);
|
||
66 | sys_outb(0x64, 0x60);
|
||
67 | sys_outb(0x64, scancode); */
|
||
68 | |||
69 | printf("%x\n", scancode);
|
||
70 | 7 | up20180614 | //kbc_ih();
|
71 | 5 | up20180614 | printf("\n");
|
72 | 6 | up20180614 | while (scancode !=
|
73 | 8 | up20180614 | EXIT_CODE) |
74 | { /* You may want to use a different condition */
|
||
75 | 5 | up20180614 | /* Get a request message. */
|
76 | // printf("1\n");
|
||
77 | // printf("cont:%d, time:%d\n\n",cont/60,time);
|
||
78 | if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) { |
||
79 | printf("driver_receive failed with: %d", r);
|
||
80 | continue;
|
||
81 | 4 | up20180614 | } |
82 | if (is_ipc_notify(ipc_status)) { /* received notification */ |
||
83 | 5 | up20180614 | switch (_ENDPOINT_P(msg.m_source)) {
|
84 | case HARDWARE: /* hardware interrupt notification */ |
||
85 | if (msg.m_notify.interrupts & BIT(0)) { /* subscribed interrupt */ |
||
86 | |||
87 | 7 | up20180614 | #ifdef LAB3
|
88 | cnt++; |
||
89 | #endif
|
||
90 | 5 | up20180614 | sys_inb(0x64, &scancode);
|
91 | if (scancode & 0x01) { |
||
92 | 7 | up20180614 | #ifdef LAB3
|
93 | cnt++; |
||
94 | #endif
|
||
95 | 5 | up20180614 | sys_inb(0x60, &scancode);
|
96 | 6 | up20180614 | if (scancode != 0xe0 && flag == 0) { |
97 | // tickdelay(micros_to_ticks(DELAY_US));
|
||
98 | 5 | up20180614 | scan_arr[0] = scancode;
|
99 | kbd_print_scancode(!(scancode & 0x80), 1, scan_arr); |
||
100 | } |
||
101 | |||
102 | 6 | up20180614 | else if (scancode == 0xe0) { |
103 | scan_arr[0] = scancode;
|
||
104 | flag = 1;
|
||
105 | 5 | up20180614 | } |
106 | |||
107 | 6 | up20180614 | else if (flag == 1) { |
108 | 5 | up20180614 | scan_arr[1] = scancode;
|
109 | kbd_print_scancode(!(scancode & 0x80), 2, scan_arr); |
||
110 | 6 | up20180614 | flag = 0;
|
111 | 5 | up20180614 | } |
112 | 6 | up20180614 | } |
113 | 5 | up20180614 | |
114 | 4 | up20180614 | } |
115 | 5 | up20180614 | // printf("msg:%x\n",msg.m_notify.interrupts);
|
116 | break;
|
||
117 | default:
|
||
118 | // printf("2\n");
|
||
119 | break; /* no other notifications expected: do nothing */ |
||
120 | } |
||
121 | 4 | up20180614 | } else {
|
122 | 5 | up20180614 | // printf("3\n"); /* received a standard message, not a notification */
|
123 | /* no standard messages expected: do nothing */
|
||
124 | 4 | up20180614 | } |
125 | 5 | up20180614 | } |
126 | 7 | up20180614 | kbd_print_no_sysinb(cnt); |
127 | 5 | up20180614 | if (sys_irqrmpolicy(&hook_id) != 0) |
128 | return 1; |
||
129 | 4 | up20180614 | |
130 | return 0; |
||
131 | } |
||
132 | |||
133 | int(kbd_test_poll)() {
|
||
134 | /* To be completed by the students */
|
||
135 | 8 | up20180614 | uint32_t key=0;
|
136 | 6 | up20180614 | uint8_t scan_arr[2] = {0, 0}; |
137 | int flag = 0; |
||
138 | 7 | up20180614 | uint32_t cnt=0;
|
139 | 8 | up20180614 | sys_outb(0x64,0x20); //enable interrupts again |
140 | |||
141 | sys_outb(0x64, 0x60); |
||
142 | sys_inb(0x60,&key);
|
||
143 | 6 | up20180614 | while(scancode != EXIT_CODE)
|
144 | { |
||
145 | tickdelay(micros_to_ticks(DELAY_US)); |
||
146 | 7 | up20180614 | #ifdef LAB3
|
147 | cnt++; |
||
148 | #endif
|
||
149 | 6 | up20180614 | sys_inb(0x64, &scancode);
|
150 | if (scancode & 0x01) { |
||
151 | 7 | up20180614 | #ifdef LAB3
|
152 | cnt++; |
||
153 | #endif
|
||
154 | 6 | up20180614 | sys_inb(0x60, &scancode);
|
155 | if (scancode != 0xe0 && flag == 0) { |
||
156 | scan_arr[0] = scancode;
|
||
157 | kbd_print_scancode(!(scancode & 0x80), 1, scan_arr); |
||
158 | } |
||
159 | 4 | up20180614 | |
160 | 6 | up20180614 | else if (scancode == 0xe0) { |
161 | scan_arr[0] = scancode;
|
||
162 | flag = 1;
|
||
163 | } |
||
164 | |||
165 | else if (flag == 1) { |
||
166 | scan_arr[1] = scancode;
|
||
167 | kbd_print_scancode(!(scancode & 0x80), 2, scan_arr); |
||
168 | flag = 0;
|
||
169 | } |
||
170 | } |
||
171 | } |
||
172 | 7 | up20180614 | kbd_print_no_sysinb(cnt); |
173 | 8 | up20180614 | sys_outb(0x64,0x60); //enable interrupts again |
174 | sys_outb(0x60, key | BIT(0)); //enable interrupts again |
||
175 | return 0; |
||
176 | 4 | up20180614 | } |
177 | |||
178 | int(kbd_test_timed_scan)(uint8_t n) {
|
||
179 | /* To be completed by the students */
|
||
180 | 8 | up20180614 | uint8_t scan_arr[2] = {0, 0}; |
181 | int flag=0; |
||
182 | int ipc_status;
|
||
183 | message msg; |
||
184 | uint8_t r; |
||
185 | uint8_t bit_no_timer = 0, bit_no_kbd = 1; |
||
186 | int hook_id_kbd=bit_no_kbd, hook_id_timer=bit_no_timer;
|
||
187 | int cont=0,cnt=0; |
||
188 | |||
189 | sys_irqsetpolicy(IRQ_TIMER,IRQ_REENABLE,&hook_id_timer); |
||
190 | sys_irqsetpolicy(IRQ_KB, IRQ_REENABLE | IRQ_EXCLUSIVE, &hook_id_kbd); |
||
191 | kbc_ih(); |
||
192 | while( (cont/DEFAULT_FREQ)<n && scancode !=EXIT_CODE) //se não atingir o tempo de espera nem a tecla for ESC |
||
193 | { |
||
194 | /* You may want to use a different condition */
|
||
195 | /* Get a request message. */
|
||
196 | // printf("1\n");
|
||
197 | //printf("cont:%d, time:%d\n\n",cont/60,time);
|
||
198 | if ( (r = driver_receive(ANY, &msg, &ipc_status)) != 0 ) |
||
199 | { |
||
200 | printf("driver_receive failed with: %d", r);
|
||
201 | continue;
|
||
202 | } |
||
203 | if (is_ipc_notify(ipc_status)) {
|
||
204 | switch (_ENDPOINT_P(msg.m_source)) {
|
||
205 | case HARDWARE:
|
||
206 | if (msg.m_notify.interrupts & BIT(bit_no_timer)) {
|
||
207 | cont++; |
||
208 | if(cont%DEFAULT_FREQ==0) |
||
209 | timer_print_elapsed_time(); |
||
210 | //printf("cont:%d\n",cont);
|
||
211 | } |
||
212 | if (msg.m_notify.interrupts & BIT(bit_no_kbd))
|
||
213 | { |
||
214 | |||
215 | #ifdef LAB3
|
||
216 | cnt++; |
||
217 | #endif
|
||
218 | sys_inb(0x64, &scancode);
|
||
219 | if (scancode & 0x01) { |
||
220 | #ifdef LAB3
|
||
221 | cnt++; |
||
222 | #endif
|
||
223 | sys_inb(0x60, &scancode);
|
||
224 | if (scancode != 0xe0 && flag == 0) |
||
225 | { |
||
226 | |||
227 | scan_arr[0] = scancode;
|
||
228 | kbd_print_scancode(!(scancode & 0x80), 1, scan_arr); |
||
229 | } |
||
230 | 4 | up20180614 | |
231 | 8 | up20180614 | else if (scancode == 0xe0) |
232 | { |
||
233 | scan_arr[0] = scancode;
|
||
234 | flag = 1;
|
||
235 | } |
||
236 | |||
237 | else if (flag == 1) |
||
238 | { |
||
239 | scan_arr[1] = scancode;
|
||
240 | kbd_print_scancode(!(scancode & 0x80), 2, scan_arr); |
||
241 | flag = 0;
|
||
242 | } |
||
243 | cont=0;
|
||
244 | } |
||
245 | //printf("msg:%x\n",msg.m_notify.interrupts);
|
||
246 | break;
|
||
247 | default:
|
||
248 | //printf("2\n");
|
||
249 | break; /* no other notifications expected: do nothing */ |
||
250 | } |
||
251 | } |
||
252 | // printf("3\n"); /* received a standard message, not a notification */
|
||
253 | /* no standard messages expected: do nothing */
|
||
254 | |||
255 | } |
||
256 | } |
||
257 | kbd_print_no_sysinb(cnt); |
||
258 | |||
259 | if(sys_irqrmpolicy(&hook_id_timer)!=0) return 1; |
||
260 | if(sys_irqrmpolicy(&hook_id_kbd)!=0) return 1; |
||
261 | |||
262 | |||
263 | return 0; |
||
264 | |||
265 | |||
266 | //printf("%s is not yet implemented!\n", __func__);
|
||
267 | |||
268 | |||
269 | 4 | up20180614 | } |