11 #include <hardware/pit.h> 14 #define PIT_CHANNEL(c) (0x40 + (c)) 16 #define PIT_FREQ 1193182 17 #define MODE_RATE 0x02 18 #define MS_TO_TICKS(ms, freq) ((freq) * (ms) / 1000) // freq = ticks/1s = ticks/1000ms, so ticks = freq*1000ms 27 static uint32_t freq = 0;
28 static uint32_t seconds = 0, minutes = 0, hours = 0, ticks = 0;
30 uint8_t pit_init_channel(uint8_t channel, uint8_t mode, uint32_t freq) {
31 if (freq < 19 || freq > PIT_FREQ / 2)
35 uint16_t counter = PIT_FREQ / freq;
41 pit_init_t init = {.fmt = 0, .mode = mode, .byte = 3, .chan = channel};
42 outb(PIT_INIT, *(uint8_t*) &init);
43 outb(PIT_CHANNEL(channel), counter & 0xFF);
44 outb(PIT_CHANNEL(channel), counter >> 8);
50 if (ticks % freq == 0) {
52 if (seconds % 60 == 0) {
55 if (minutes % 60 == 0) {
65 void pit_init(uint32_t new_freq) {
66 print(
"PIT init ... ");
68 if (pit_init_channel(0, MODE_RATE, new_freq)) {
70 println(
"%2aok%a. Frequency=%dHz.", freq);
72 println(
"%4afail%a. Frequency must be > 18Hz and < 0.59MHz.");
75 void pit_dump_time() {
76 print(
"%02d:%02d:%02d", hours, minutes, seconds);
80 __attribute__((optimize(
"O0")))
void pit_sleep(uint32_t ms) {
81 uint32_t wait_until = ticks + MS_TO_TICKS(ms, freq);
82 while (wait_until < ticks);
83 while (ticks < wait_until);
94 .wait_until = ticks + MS_TO_TICKS(ms, freq),
95 .state = PIT_WAITING_UNTIL_OVERFLOW
101 switch (timeout->state) {
102 case PIT_WAITING_UNTIL_OVERFLOW:
103 if (!(timeout->wait_until < ticks))
104 timeout->state = PIT_WAITING_UNTIL_TIMEOUT;
106 case PIT_WAITING_UNTIL_TIMEOUT:
107 if (!(ticks < timeout->wait_until)) {
108 timeout->state = PIT_TIMED_OUT;
cpu_state_t * schedule(cpu_state_t *cpu)
Returns the next task to run.
The CPU's state when an interrupt occurs.
#define ISR_IRQ(irq)
the interrupt vector for an IRQ
void isr_register_handler(size_t intr, isr_handler_t handler)
Registers a handler to call whenever a given interrupt is fired.