// // Created by rick on 9/22/19. // #include #include #include #include #include #include #include #include // https://wiki.osdev.org/PIT #define PIT_MODE_BIN_BCD (1 << 0) #define PIT_MODE_BIN (0 << 0) #define PIT_MODE_BCD (1 << 0) #define PIT_GENERATOR_MODE (0b111 << 1) #define PIT_MODE_INTERRUPT_ON_TERMINAL_COUNT (0b000 << 1) #define PIT_MODE_HARDWARE_RETRIGGERABLE_ONE_SHOT (0b001 << 1) #define PIT_MODE_HARDWARE_RATE_GENERATOR (0b010 << 1) #define PIT_MODE_HARDWARE_SQUARE_WAVE_GENERATOR (0b011 << 1) #define PIT_MODE_SOFTWARE_TRIGGERED_STROBE (0b100 << 1) #define PIT_MODE_HARDWARE_TRIGGERED_STROBE (0b101 << 1) #define PIT_ACCESS_MODE (0b11 << 4) #define PIT_ACCESS_MODE_LATCH_COUNT (0b00 << 4) #define PIT_ACCESS_MODE_L (0b01 << 4) #define PIT_ACCESS_MODE_H (0b10 << 4) #define PIT_ACCESS_MODE_LH (0b11 << 4) #define PIT_CHANNEL (0b11 << 6) #define PIT_CHANNEL_0 (0b00 << 6) #define PIT_CHANNEL_1 (0b01 << 6) #define PIT_CHANNEL_2 (0b10 << 6) #define PIT_CHANNEL_READ_BACK (0b11 << 6) uint32_t tick = 0; static void timer_callback(isr_registers_t *regs) { tick++; task_switch_next(); } uint32_t timer_get_tick() { return tick; } void sleep(uint32_t milliseconds) { uint32_t done = tick + milliseconds; while (tick != done) { k_wait_for_interrupt(); } } void print_current_tick() { char msg[32]; memset(msg, 0, 32); itoa(tick, msg, 10); kprint(msg); kprint("\n"); } int init_timer(uint32_t freq) { register_interrupt_handler(IRQ0, timer_callback); uint32_t divisor = 1193180 / freq; uint8_t low = (uint8_t) (divisor & 0xFF); uint8_t high = (uint8_t) ((divisor >> 8) & 0xFF); port_byte_out(PORT_PIT_COMMAND, PIT_MODE_BIN | PIT_MODE_HARDWARE_SQUARE_WAVE_GENERATOR | PIT_ACCESS_MODE_LH | PIT_CHANNEL_0); port_byte_out(PORT_PIT_DATA_0, low); port_byte_out(PORT_PIT_DATA_0, high); return 0; }