Timer compare match interrupt by writing CNT

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi.

I was hoping to get a timer compare match interrupt by setting the value I want to match in CCA and then writing the value to compare into CNT. DMA would be used to update CNT automatically with bytes from the USART, giving me a character match interrupt.

Unfortunately it does not work.

	TCF0.CTRLA = 0;
	TCF0.CTRLB = TC0_CCAEN_bm;
	TCF0.CTRLC = 0;
	TCF0.CTRLD = 0;
	TCF0.CTRLE = 0;//TC_BYTEM_BYTEMODE_gc;

	TCF0.INTFLAGS = 0xFF;	// clear any outstanding interrupts
	TCF0.INTCTRLA = 0;
	TCF0.INTCTRLB = TC_CCAINTLVL_LO_gc;

	TCF0.PER = 0xFFF;
	TCF0.CCA = 0xAB;
	TCF0.CNT = 0;

	while (1)
	{
		delay_ms_auto(250);
		TCF0.CNT = 0xAB;
		delay_ms_auto(1);
		TCF0.CNT = 0;
	}

The interrupt is not triggered. I checked that it works by setting the timer to just freely run and it does. I tried adding the following just in case the timer needed to be active:

TCF0.CTRLA = TC_CLKSEL_EVCH7_gc;

Didn't help though.

Has anyone had any luck doing this? The A3U manual says that the CCA value is continuously compared to CNT, but that can't really be true because otherwise the interrupt would keep re-triggering all the time they were the same. It seems that actually it is only compared when the timer is clocked.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I haven't looked at the details, but I can't see you enable interrupts in PMIC.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah, okay, I found a way to trigger the interrupt. After setting CNT I clock the timer with a software generated event...

EVSYS.STROBE = (1<<7);

The match interrupt executes. Apparently the test is made on the clock edge following the point at which CNT matches. If I set CNT to one lower than my match value so that the event increments it to make CNT==CCA it doesn't work.

The datasheet's claim that the two are continuously compared is highly misleading! :)

Let's see if it will work with DMA...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay, I made it work. Bit tricky but now I can receive all the GPS data I need with a single interrupt per second.

The key is that GPS receivers transmit their data in batches. You get a bunch of sentences all sent one after another on most chipsets. The GlobalTop model I am using can be set to only send RMC and its own proprietary sentence which can't be turned off. So every second it sends something like this:

$GTOP,11,2*6E
$GPRMC,161505.086,V,,,,,0.00,0.00,231112,,,N*47

DMA receives bytes from the USART and stores them in a buffer. Whenever the RX pin sees a falling edge an event resets a timer. If the timer ever reaches 100ms it generates an interrupt that decodes the data in the buffer and resets the DMA reach for the next batch.

The new XMEGA-E chips seem to have a compare-match thing built in to DMA which could do this much more easily, but oh well. This works.