Page 1 of 1

IRQ question

Posted: Mon Jun 07, 2010 9:56 pm
by halofreak1990
Hi, I've been searching around the web for some method to read from the RealTime Clock.
The code I found uses the RTC IRQ, which is 8, or 40, after remapping.
Anyways, I set a handler for it using setvect, and it simply won't fire.
I've read somewhere that I might be required to unmask the IRQ, or something,
but I couldn't find such code doing that for the keyboard or floppy to use as a reference.
I have the code waiting for the IRQ to fire, so my OS hangs right there.

Here's the code that sets up the IRQ, I pass it 40 as IRQ, which should work, based on the tut's IRQ mappings.

Code: Select all

void rtc_install(int irq)
{
    unsigned char status;

    write_register(0x0A, read_register(0x0A) | 0x0F); // important line here
    
    status = read_register(0x0B);
    status |=  0x02;             // 24 hour clock
    status |=  0x10;             // update ended interrupts
    status &= ~0x20;             // no alarm interrupts
    status &= ~0x40;             // no periodic interrupt
    bcd     =  !(status & 0x04); // check if data type is BCD
    write_register(0x0B, status);

    read_register(0x0C);

    setvect(irq, rtc_handler);
    
	while(!Interrupt); // pause till interrupt
}
I know the last line actually makes it hang, since its waiting for an interrupt which never fires, but I'm not gonna remove it, since it ensures that when I later down the road read out values, it's actually returning something.

Re: IRQ question

Posted: Tue Jun 08, 2010 1:36 pm
by pathos
To unmask an IRQ, you can do this:

Code: Select all

void enable_irq(int irq)
{
	if(irq == 16)
	{
		outportb(0x21, ~0xFF);
		outportb(0xA1, ~0xFF);
	}
	else if (irq >= 0 && irq < 8)
	{
		unsigned char irqmask = inportb(0x21);
		irqmask &= (1 << irq);
		outportb(0x21, irqmask);
	}
	else if (irq >7 && irq < 16)
	{
		unsigned char irqmask = inportb(0xA1);
		irqmask &= (1 << irq);
		outportb(0xA1, irqmask);
	}
}
Not sure if that will fix your problem however, but you can give it shot.

Re: IRQ question

Posted: Tue Jun 08, 2010 4:55 pm
by Andyhhp
You will generally have to some programming of the RTC chip to tell it to fire.

I have no experience using it but in general, you can just insert an interrupt handler and expect everything else to be set up correctly.

~Andrew

Re: IRQ question

Posted: Wed Jun 09, 2010 2:45 am
by accelleon
Info on the RTC: http://wiki.osdev.org/RTC (MUST READ THIS)
Writing/reading the date to/from the RTC: http://wiki.osdev.org/CMOS#The_Real-Time_Clock (read this if you want to get the date from the RTC)

Hope that helps.

BTW wiki.osdev.org is an awesome resource for os developers :D

Re: IRQ question

Posted: Wed Jun 09, 2010 6:13 pm
by halofreak1990
I've been reading through the articles, and I have a question; do I need to set an interrupt to use the RTC?
Or would it be sufficient to read the RTC once, and increment the recieved data to simulate a clock?

Also, I've read about the NMI's and I'm thinking of designing a handler for those, since it would be nice to inform the user about a (non-fatal) hardware failure, so he/she can take the action required to correct this.

Re: IRQ question

Posted: Thu Jun 10, 2010 12:17 am
by accelleon
no the interrupt doesn't need to be set.

to simulate a clock you could read from the RTC at startup, then use the PIT to increment the value.

the NMI only needs to be disabled when programming the RTC, however if you wish to have a handler for the NMI (which can be very useful in the even of hardware failures).

BTW: NMI that isn't caused by a memory read or write failure is an unrecoverable hardware failure. so if an NMI was triggered and it wasn't a memory failure, well then your gonna need to tell the user that they've got a faulty piece of hardware in their box.

Re: IRQ question

Posted: Tue Jun 15, 2010 10:58 pm
by halofreak1990
accelleon wrote:no the interrupt doesn't need to be set.
to simulate a clock you could read from the RTC at startup, then use the PIT to increment the value.
I've decided to ditch the irq handler for the RTC and read the values directly whenever I need.
Also, I check for the BCD flag and modify the returned variables as needed.
Now I only need to add checking for 24h/12h time and I'll be done with the clock.
accelleon wrote:BTW: NMI that isn't caused by a memory read or write failure is an unrecoverable hardware failure. so if an NMI was triggered and it wasn't a memory failure, well then your gonna need to tell the user that they've got a faulty piece of hardware in their box.
Better to tell the user something's wrong than to let them wonder why certain things don't work :wink:

EDIT: I read somewhere that, strangely, the RTC, though connected to IRQ8, will actually trigger IRQ 70h, perhaps I had to handle that one.
Also, fool that I was, failed to realize the OS from the tutorial here already has an NMI handler. I only need to modyfy it to display something useful instead of the standard "NMI Trap" message.

Re: IRQ question

Posted: Tue Jun 22, 2010 10:21 pm
by ehenkes
https://prettyos.svn.sourceforge.net/sv ... nel/time.c

Code: Select all

uint8_t PackedBCD2Decimal(uint8_t PackedBCDVal)
{
    return ((PackedBCDVal >> 4) * 10 + (PackedBCDVal & 0xF));
}