parent
7b3b59bf1e
commit
491f9d0d4a
@ -0,0 +1,43 @@
|
|||||||
|
use syscall::io::{Io, Pio};
|
||||||
|
|
||||||
|
static mut PIT: Pit = Pit::new(0x40);
|
||||||
|
|
||||||
|
pub fn init() {
|
||||||
|
assert_has_not_been_called!("pit::init must be called only once");
|
||||||
|
unsafe{ PIT.init(100); }
|
||||||
|
debug!("pit: init end");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Pit {
|
||||||
|
chan0: Pio<u8>,
|
||||||
|
chan1: Pio<u8>,
|
||||||
|
chan2: Pio<u8>,
|
||||||
|
command: Pio<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pit {
|
||||||
|
const fn new(port: u16) -> Self {
|
||||||
|
Pit {
|
||||||
|
chan0: Pio::new(port),
|
||||||
|
chan1: Pio::new(port+1),
|
||||||
|
chan2: Pio::new(port+2),
|
||||||
|
command: Pio::new(port+3),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn init(&mut self, freq: u32) {
|
||||||
|
self.command.write(TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
|
||||||
|
let div = Pit::divisor(freq);
|
||||||
|
self.chan0.write((div & 0xFF) as u8);
|
||||||
|
self.chan0.write((div >> 8) as u8);
|
||||||
|
}
|
||||||
|
fn divisor(freq: u32) -> u16 {
|
||||||
|
let div = (TIMER_FREQ + freq / 2) / freq;
|
||||||
|
assert!(div < 0x10000);
|
||||||
|
div as u16
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const TIMER_FREQ : u32 = 1193182;
|
||||||
|
const TIMER_SEL0 : u8 = 0x00; // select counter 0
|
||||||
|
const TIMER_RATEGEN : u8 = 0x04; // mode 2, rate generator
|
||||||
|
const TIMER_16BIT : u8 = 0x30; // r/w counter 16 bits, LSB first
|
Loading…
Reference in new issue