explanation of logomatic IRQ frequency asked

I tried to understand the frequency working of the logging but do not understand how it calculates the counter value for IRQ.

The T0MR0 = 58982400 / freq; should match the clock speed of 12 mHz at a frequency of 1Hz. It is 4,9 times bigger. I tested the frequency and it really works at 20Hz.

Does anyone know how it works?

This is the timer setup code:

void mode_2(void)

{

rprintf(“MODE 2\n\r”);

enableIRQ();

// Timer0 interrupt is an IRQ interrupt

VICIntSelect &= ~0x00000010;

// Enable Timer0 interrupt

VICIntEnable |= 0x00000010;

// Use slot 2 for UART0 interrupt

VICVectCntl2 = 0x24;

// Set the address of ISR for slot 1

VICVectAddr2 = (unsigned int)MODE2ISR;

T0TCR = 0x00000002; // Reset counter and prescaler

T0MCR = 0x00000003; // On match reset the counter and generate interrupt

T0MR0 = 58982400 / freq;

T0PR = 0x00000000; // Disable preset register

T0TCR = 0x00000001; // enable timer

stringSize = 512;

mode_action();

}

In effect the processor runs at 60mHz due to PLL on a 12mHz crystal

The number given for T0MR0 can be devided by integers to make proper baud rates. In reality the IRQ frequency is 1,7% off so if you want an exact logging of 20Hz you have to put in a number of 60000000/20 = 3000000

I found a lot if useful tutorials on http://csserver.evansville.edu/~blandfo … RMLecture/

pilot:
I found a lot if useful tutorials on http://csserver.evansville.edu/~blandfo … RMLecture/

I appreciate people who share insight but please stay alert when reading them.

Following that link, I went straight for what I was interested in: interruptions settings (lecture 7).

All in all a pretty good overview of the mechanism although I would argue that the processor documentation is more complete and accurate.

But nowadays who wants to RTFM? After all I was looking for a shortcut too.

I skimmed all the blabla at the beginning until page 5 where he explains how he uses a |= to enable the interrupt:

"Note that we use a |= (or equals) operator so as not to change the status of other interrupts.
VICIntEnable |= 0x00000010; //Enable the interrupts"

And Bam! He walks right into the trap.

|= does a read-modify-write: it reads the register, modifies the value read and writes it back again.

The problem is if an interrupt that also modifies the register occurs between the read and the write - in that case what he writes back is the modified original value, without the modification made by the interruption.

How to solve that problem?

If he had read the description of the register that he obligingly provides just two lines above he would have seen that just writing VICIntEnable = 0x00000010 does exactly what he wants: zeroes are ignored.

This is the whole point of this type of registers: avoid the read-modify-write.

Instead, his pupils risk having interrupts that mysteriously remain active or get deactivated from time to time.

Even with a good debugger, finding this kind of issues is likely to be arduous.