1 /* 2 * programmable interrupt timer 3 */ 4 5 #include "u.h" 6 #include "../port/lib.h" 7 #include "mem.h" 8 #include "dat.h" 9 #include "fns.h" 10 #include "io.h" 11 #include "ureg.h" 12 13 enum { 14 /* piscr */ 15 PTE = 1<<0, 16 PITF = 1<<1, 17 PIE = 1<<2, 18 PS = 1<<7, 19 }; 20 21 static void 22 pitinterrupt(Ureg*, void*) 23 { 24 IMM *io; 25 26 io = m->iomem; 27 if(io->piscr & PS){ 28 io->piscr |= PS; /* clear by writing 1 */ 29 /* do whatever is required */ 30 } 31 } 32 33 static void 34 pitreset(void) 35 { 36 IMM *io; 37 38 io = ioplock(); 39 io->piscrk = KEEP_ALIVE_KEY; 40 io->piscr = (PITlevel<<8) | PS | PITF; 41 if(0) 42 io->piscrk = ~KEEP_ALIVE_KEY; 43 /* piscrk is left unlocked for interrupt routine */ 44 iopunlock(); 45 intrenable(PITlevel, pitinterrupt, nil, BUSUNKNOWN, "pit"); 46 } 47 48 static ulong 49 pitload(ulong usec) 50 { 51 IMM *io; 52 ulong v; 53 54 v = ((usec*m->oscclk)/512); 55 if(v == 0 || v >= (1<<16)) 56 return 0; /* can't do */ 57 io = ioplock(); 58 io->pitck = KEEP_ALIVE_KEY; 59 io->pitc = (v-1)<<16; 60 io->pitck = ~KEEP_ALIVE_KEY; 61 io->piscrk = KEEP_ALIVE_KEY; 62 io->piscr = (PITlevel<<8) | PS | PIE | PITF | PTE; 63 if(0) 64 io->piscrk = ~KEEP_ALIVE_KEY; 65 /* piscrk is left unlocked for interrupt routine */ 66 iopunlock(); 67 return (v*512)/m->oscclk; 68 } 69