Page 1 of 1

Trouble with CMOS RTC (x86)

Posted: Sun Jan 24, 2010 9:04 am
by jimka
Hello, I've recently made a stab at OS development but I've seem to have hit a snag.

I'm trying to program the CMOS RTC, but I can seemingly only make the interrupt fire once. I've read that you have to read the 0xC register to make it fire multiple times but whatever I do, I cannot seem to make it work.

Here's the code I'm trying to make work:

Some defines

Code: Select all

#define CMOS 0x70
#define CMOSI 0x71
Helper functions

Code: Select all

uint8 get(uint8 part) {
	outb(CMOS, part);
	return inb(CMOSI);
}

void set(uint8 part, uint8 value) {
	outb(CMOS, part);
	outb(CMOSI, value);
}
Init code (remapped IRQ, IRQ8 = interrupt number 40)

Code: Select all

void Clock_Init() {
	ReadDate();

	// Install the RTC interrupt.
	InstallInterruptCallback(40, RTC_callback);
	uint8 regB = get(0xB) | 0x40;
	set(0xB, regB);
}
RTC callback

Code: Select all

void RTC_callback(registers_t regs) {
	static int ticks = 0;

	printf(".\n");
	ticks++;

	if(ticks % 1024) {
		if(c.second >= 60) {
			ReadDate();
		}

		ticks = 0;
	}

	// Read status register C so the interrupt will fire again. (not working atm).
	uint8 c = get(0xC);
}

Re: Trouble with CMOS RTC (x86)

Posted: Sun Jan 24, 2010 9:58 am
by Gigasoft
This may be a stupid question, but do you remember to send an EOI in your ISR?

Re: Trouble with CMOS RTC (x86)

Posted: Sun Jan 24, 2010 12:13 pm
by jimka
I thought I did, but I apparently had a minor bug in it:

Old one:

Code: Select all

void irq_handler(registers_t regs) {
	void (*irq)(registers_t) = func[regs.int_no];

	if(irq != 0) {
		irq(regs);
	} else {
		printf("Unhandled interrupt fired: %d.\n", regs.int_no);
	}

	if(regs.int_no > 31) {
		// Send EOI (End of Interrupt) signal to the PICs

		// If interrupt originated from the slave PIC, reset it.
		if(regs.int_no > 40) {
			outb(PICS, EOI);
		}

		// Reset the master PIC.
		outb(PICM, EOI);
	}
}
That should have been 'if(regs.int_no >= 40) ....', and this one also lead me to another piece of code that was in error, namely the one updating the clock. Thanks for suggestion.