Programming PIT

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
0xnlbs
Posts: 9
Joined: Mon Apr 21, 2014 4:20 am

Programming PIT

Post by 0xnlbs »

I an trying to print a message on screen periodically. This is my code from http://www.osdever.net/bkerndev/Docs/pit.htm

unsigned ticks_counter = 0;

Code: Select all

void timer_phase(int hz){
    int divisor = 1193180 / hz;       /* Calculate our divisor */
    port_byte_out(0x43, 0x36);             /* Set our command byte 0x36 */
    port_byte_out(0x40, divisor & 0xFF);   /* Set low byte of divisor */
    port_byte_out(0x40, divisor >> 8);     /* Set high byte of divisor */
}

void timer_handler(struct registers_state *r){
	/* Increment our 'tick count' */
    ticks_counter++;

    /* Every 18 clocks (approximately 1 second), we will
    *  display a message on the screen */
    if (ticks_counter){
        char ts_buff[8];
        pocha_vga_draws(itoa(ticks_counter, ts_buff), pocha_vga_color(VGA_COLOR_Red, VGA_COLOR_White), 0, 0);
    }
}

void timer_install(){
	irq_install_handler(0, timer_handler);
}
Problem #1: But My timer_handler fires only once.

Also I cannot understand meaning of 0x36 (0 011 01 10)
according to http://wiki.osdev.org/Programmable_Inte ... .2FO_Ports

Problem #2:
Its using lowbyte(0 1 = Access mode: lobyte only) only and channel 2 (1 0 = Channel 2)
But its supposed to use channel 0
Last edited by 0xnlbs on Thu May 08, 2014 1:35 am, edited 1 time in total.
User avatar
Shaun
Member
Member
Posts: 43
Joined: Mon Sep 17, 2012 3:14 am
Contact:

Re: Programming PIT

Post by Shaun »

0xnlbs wrote:
But My timer_handler fires only once.
do you send EOI to PIC when exiting interrupt handler?
0xnlbs
Posts: 9
Joined: Mon Apr 21, 2014 4:20 am

Re: Programming PIT

Post by 0xnlbs »

Yes attaching my irq_handler that calls timer_handler

Code: Select all

void _irq_handler(struct registers_state* registers){

    /* This is a blank function pointer */
    void (*handler)(struct registers_state *registers);

    /* Find out if we have a custom handler to run for this
    *  IRQ, and then finally, run it */
    char ino_str[3];
    pocha_vga_draws(itoa(registers->int_no - 32, ino_str), pocha_vga_color(VGA_COLOR_Yellow, VGA_COLOR_LightRed), 0, 0);
    handler = irq_routines[registers->int_no - 32];
    if(handler){
        handler(registers);
    }
    else blank_handler(registers);

    /* If the IDT entry that was invoked was greater than 40
    *  (meaning IRQ8 - 15), then we need to send an EOI to
    *  the slave controller */
    if (registers->int_no >= 40){
        port_byte_out(0xA0, 0x20);
    }

    /* In either case, we need to send an EOI to the master
    *  interrupt controller too */
    port_byte_out(0x20, 0x20);
}
0xnlbs
Posts: 9
Joined: Mon Apr 21, 2014 4:20 am

Re: Programming PIT

Post by 0xnlbs »

silly silly one. somehow I commented out the infinite loop at the end of main.

But I still don;t understand the meaning of 0x36 So one Problem #1 persists. thread unsolved.
Last edited by 0xnlbs on Thu May 08, 2014 2:10 am, edited 1 time in total.
User avatar
bwat
Member
Member
Posts: 359
Joined: Fri Jul 03, 2009 6:21 am

Re: Programming PIT

Post by bwat »

It's the shape of the clock output (duty cycle). Mode 3 for square waves fit for a baud rate generator, mode 2 for pulses for a real-time clock interrupt.

I googled "8254 datasheet" and the PDF of the Intel datasheet was the first result. Go look at page 10 of that document for more info.

[Edit: after looking at Shaun's answer below I see I assumed you only had a problem with the mode. Don't ask me why! Anyway, check out the whole document. It's always good to go to the source.]
Last edited by bwat on Thu May 08, 2014 3:17 am, edited 1 time in total.
Every universe of discourse has its logical structure --- S. K. Langer.
User avatar
Shaun
Member
Member
Posts: 43
Joined: Mon Sep 17, 2012 3:14 am
Contact:

Re: Programming PIT

Post by Shaun »

0xnlbs wrote:silly silly one. somehow I commented out the infinite loop at the end of main.

But I still don;t understand the meaning of 0x36 So one Problem #1 persists. thread unsolved.
0x36 = 00110110B

so

BCD = 0, means we will write a 16 bit counter next
MODE = 011, Square Wave Mode
RW = 11, ( 3 = LSB then MSB)
CNTR = 00, tell pic we use counter 0

To set channel 0's Data register, we need to select counter 0 and some modes in the Command register first.
0xnlbs
Posts: 9
Joined: Mon Apr 21, 2014 4:20 am

Re: Programming PIT

Post by 0xnlbs »

@Shaun: If I arrange it from left to right as per your answer it will be

Code: Select all

Expected: 0 011 11 00
But 0x36: 0 011 01 10
Both are not same
User avatar
Shaun
Member
Member
Posts: 43
Joined: Mon Sep 17, 2012 3:14 am
Contact:

Re: Programming PIT

Post by Shaun »

0xnlbs wrote:@Shaun: If I arrange it from left to right as per your answer it will be

Code: Select all

Expected: 0 011 11 00
But 0x36: 0 011 01 10
Both are not same
no,you misunderstanding,perhaps.

0x36 = 00 11 011 0

Expected:
chanel (6-7) :00
access mode(4-5):11, first lobyte then hibyte
operating mode(1-3):011, Mode 3 (square wave generator)
BCD/Binary mode:0, 0 = 16-bit binary

so, from left to right, the command we need to set is 00 11 011 0 == 0x36
0xnlbs
Posts: 9
Joined: Mon Apr 21, 2014 4:20 am

Re: Programming PIT

Post by 0xnlbs »

Yes I misunderstood. I thought its either all left to right or all right to left. But I see now its right to left but individual values are from left to right.

Thanks
Post Reply