Timer/Counter register B compare bug.

Discussion about SAM7 Series and ARM7TDMI based products.

Moderator: nferre

ThaddeusMorgan
Posts: 37
Joined: Thu Dec 22, 2005 9:35 pm

Timer/Counter register B compare bug.

Wed Mar 08, 2006 5:00 am

This post concerns a Timer/Counter bug relevant to all Timer/Counters
(0, 1, and 2). In particular, given a Timer/Counter configured to be in
Waveform mode with the register B compare interrupt enabled, the register
B compare interrupt never fires. The expected behavior is for the
register B compare interrupt to fire. Register A and register C compare
interrupts fire as expected.

Choosing one of three lines of code below to enable Timer/Counter 0
interrupts gives the result listed in the corresponding comment. This is
the only line of code that needs to be changed to demonstrate this bug.

TC0_IER = TC0_IER_CPAS_MASK; // Works fine.
TC0_IER = TC0_IER_CPBS_MASK; // Interrupt routine is never called.
TC0_IER = TC0_IER_CPCS_MASK; // Works fine.

Note that the Timer/Counter is in Waveform mode, not in Capture mode. In Capture mode the register B load interrupt is conditional on the register A load
interrupt. Page 393 of the AT91SAM7S Series Preliminary full datasheet
(6175C-ATARM-05-Dec-05) states:

"Depending on the WAVSEL parameter in TC_CMR (Channel Mode Register), the
behavior of TC_CV varies. With any selection, RA, RB and RC can all be
used as compare registers."

This does not appear to be true for RB. The errata sheet does not list
anything concerning the Timer/Counters.

Any suggestions? Has anyone else had this problem?

Thanks,
TM
seadog
Location: Texas
Posts: 109
Joined: Fri Sep 23, 2005 6:20 pm

Thu Apr 13, 2006 10:28 pm

Mt ATMEL FAE forwarded my TC1 RB compare interrunt NOT test program to the factory, and this is the factory response:
Customer is using the TC in Waveform mode, in this mode TIOB can be used as Output or as external event so Input. Selection is done with the field EEVT in TCx_CMR. If TIOB is chosen as the external event signal, it is configured as an input and no longer generates waveforms. Moreover, RB compare interrupt is not available in that case.
I'm not sure what it means, but I haven't been able to find anything in the datasheet that says that when in waveform mode the RB compare interrupt won't work unless TIOB is configured some specific way.

In my app I'm not trying to use TIOB as an input or an output... it's a generic I/O pin for me. Do you know what this response is referring to when it talks about the RB compare interrupt not being available in that case? Again, I can't find anything in the datasheet that seems applicable to the factory response.
seadog
Location: Texas
Posts: 109
Joined: Fri Sep 23, 2005 6:20 pm

Fri Apr 14, 2006 5:03 pm

I found that if I made the change highlighted below (suggested to me by an ATMEL factory rep) to my TC1 init routine, then TC1's RB compare interrupt started working. I've been struggling with trying to understand how this change should've been able to have any effect on this problem. As best as I can tell from reading the datasheet, the output of the MUX affected by the below change has no electrical or logical connection to the RB compare interrupt. To further muddy the waters, my init code sets up this MUX so that it's output is not routed anywhere.

Code: Select all

TC1_CMR = TCn_CMR_WM_BSWTRG(TCn_CMR_WM_EFFECT_NONE)
            | TCn_CMR_WM_BEEVT(TCn_CMR_WM_EFFECT_NONE)
            | TCn_CMR_WM_BCPC(TCn_CMR_WM_EFFECT_NONE)
            | TCn_CMR_WM_BCPB(TCn_CMR_WM_EFFECT_NONE)
            | TCn_CMR_WM_ASWTRG(TCn_CMR_WM_EFFECT_NONE)
            | TCn_CMR_WM_AEEVT(TCn_CMR_WM_EFFECT_NONE)
            | TCn_CMR_WM_ACPC(TCn_CMR_WM_EFFECT_NONE)
            | TCn_CMR_WM_ACPA(TCn_CMR_WM_EFFECT_NONE)
            | TCn_CMR_WM_MODE_WAVEFORM
            | TCn_CMR_WM_WAVESEL_UP_WITH_AUTO_TRIGGER
            | TCn_CMR_WM_EEVT_XC0  // <--- suggested change by ATMEL
            | TCn_CMR_WM_ENETRG(0)  
            | TCn_CMR_WM_EEVTEDG_NONE
            | TCn_CMR_WM_CPCDIS(0)
            | TCn_CMR_WM_CPCSTOP(0)
            | TCn_CMR_WM_BURST_GATE_NONE
            | TCn_CMR_WM_CLKI(0)
            | TCn_CMR_WM_TCCLKS_TC3
            ;
In case you're interested, here's the .H code associated with the above code snippet.

Code: Select all

//========================================================================================
// BIT DEFINITIONS FOR AT91SAM7 TC'n' CHANNEL MODE REGISTERS (TCn_CMR_WM) IN WAVEFORM MODE
//========================================================================================
                
#define TCn_CMR_WM_EFFECT_NONE   ((unsigned int) 0) // values for below 'effect' fields
#define TCn_CMR_WM_EFFECT_SET    ((unsigned int) 1)
#define TCn_CMR_WM_EFFECT_CLEAR  ((unsigned int) 2)
#define TCn_CMR_WM_EFFECT_TOGGLE ((unsigned int) 3)

#define TCn_CMR_WM_BSWTRG(x) ((unsigned int)(x) << 30) // software trigger effect on TIOB field
#define TCn_CMR_WM_BEEVT(x)  ((unsigned int)(x) << 28) // external event effect on TIOB field
#define TCn_CMR_WM_BCPC(x)   ((unsigned int)(x) << 26) // RC compare effect on TIOB field
#define TCn_CMR_WM_BCPB(x)   ((unsigned int)(x) << 24) // RB compare effect on TIOB field
#define TCn_CMR_WM_ASWTRG(x) ((unsigned int)(x) << 22) // software trigger effect on TIOA field
#define TCn_CMR_WM_AEEVT(x)  ((unsigned int)(x) << 20) // external event effect on TIOA field
#define TCn_CMR_WM_ACPC(x)   ((unsigned int)(x) << 18) // RC compare effect on TIOA field
#define TCn_CMR_WM_ACPA(x)   ((unsigned int)(x) << 16) // RA compare effect on TIOA field

#define TCn_CMR_WM_MODE_WAVEFORM ((unsigned int)(1) << 15) // enables waveform mode

#define TCn_CMR_WM_WAVESEL_UP_WITHOUT_AUTO_TRIGGER     ((unsigned int) 0 << 13) // WAVESEL field
#define TCn_CMR_WM_WAVESEL_UPDOWN_WITHOUT_AUTO_TRIGGER ((unsigned int) 1 << 13)
#define TCn_CMR_WM_WAVESEL_UP_WITH_AUTO_TRIGGER        ((unsigned int) 2 << 13)
#define TCn_CMR_WM_WAVESEL_UPDOWN_WITH_AUTO_TRIGGER    ((unsigned int) 3 << 13)

#define TCn_CMR_WM_ENETRG(x)  ((unsigned int)(x) << 12) // ENETRG field

#define TCn_CMR_WM_EEVT_TIOB ((unsigned int) 0 << 10) // EEVT field
#define TCn_CMR_WM_EEVT_XC0  ((unsigned int) 1 << 10)
#define TCn_CMR_WM_EEVT_XC1  ((unsigned int) 2 << 10)
#define TCn_CMR_WM_EEVT_XC2  ((unsigned int) 3 << 10)

#define TCn_CMR_WM_EEVTEDG_NONE    ((unsigned int) 0 << 8) // EEVTEDG field
#define TCn_CMR_WM_EEVTEDG_RISING  ((unsigned int) 1 << 8)
#define TCn_CMR_WM_EEVTEDG_FALLING ((unsigned int) 2 << 8)
#define TCn_CMR_WM_EEVTEDG_EACH    ((unsigned int) 3 << 8)

#define TCn_CMR_WM_CPCDIS(x)  ((unsigned int)(x) <<  7) // counter clock disable with RC compare field
#define TCn_CMR_WM_CPCSTOP(x) ((unsigned int)(x) <<  6) // counter clock stopped with RC compare field

#define TCn_CMR_WM_BURST_GATE_NONE ((unsigned int) 0 << 4) // BURST field
#define TCn_CMR_WM_BURST_GATE_XC0  ((unsigned int) 1 << 4)
#define TCn_CMR_WM_BURST_GATE_XC1  ((unsigned int) 2 << 4)
#define TCn_CMR_WM_BURST_GATE_XC2  ((unsigned int) 3 << 4)

#define TCn_CMR_WM_CLKI(x)    ((unsigned int)(x) <<  3) // CLKI field

#define TCn_CMR_WM_TCCLKS_TC1  ((unsigned int) 0) // TC1 = MCK / 2
#define TCn_CMR_WM_TCCLKS_TC2  ((unsigned int) 1) // TC2 = MCK / 8
#define TCn_CMR_WM_TCCLKS_TC3  ((unsigned int) 2) // TC3 = MCK / 32
#define TCn_CMR_WM_TCCLKS_TC4  ((unsigned int) 3) // TC4 = MCK / 128
#define TCn_CMR_WM_TCCLKS_TC5  ((unsigned int) 4) // TC5 = MCK / 1024
#define TCn_CMR_WM_TCCLKS_XC0  ((unsigned int) 5)
#define TCn_CMR_WM_TCCLKS_XC1  ((unsigned int) 6)
#define TCn_CMR_WM_TCCLKS_XC2  ((unsigned int) 7)
Can anyone point me to something in the datasheet that shows how this change was required in order to enable the RB compare interrupt? My project is not using the TIOA or TIOB outputs of this TC, and there's no signal applied to XC0 on my board.

Puzzled...
Seadog.
navlrac
Posts: 1
Joined: Mon Oct 31, 2011 1:35 am

Re: Timer/Counter register B compare bug.

Mon Oct 31, 2011 1:38 am

Just encountered exactly the same problem on the AT91SAM9G45, thanks for your solution. I would really have expected Atmel to document this in their datasheets by now, Its been 5 years since this issue was raised.
bptech
Posts: 25
Joined: Fri Jul 18, 2014 3:08 pm

Re: Timer/Counter register B compare bug.

Fri Jan 23, 2015 6:49 pm

6 years later, different device (ATSAM4L) same bug. They must think it is a feature, not a bug (like the old IBM company, who refused to allow anyone to say there was a bug in their software, only "undocumented features").

Code: Select all

	/* Init TC to waveform mode. */
	tc_init(TC, TC_CHANNEL_WAVEFORM,
			/* Waveform Clock Selection */
			TC_CAPTURE_TIMER_SELECTION
			| TC_CMR_WAVE /* Waveform mode is enabled */
			| TC_CMR_BCPB_SET /* RB Compare Effect: set */
			| TC_CMR_BCPC_CLEAR /* RC Compare Effect: clear */
			| TC_CMR_CPCTRG /* UP mode with automatic trigger on RC Compare */
			| TC_CMR_CPCDIS /* Disable clock when counter reaches RC */
			| TC_CMR_EEVT_XC0_OUTPUT /* Patch to make TIOB work */
);
I could not get an interrupt from RB capture until I added the last line. None of the timer inputs or outputs are actually in use, and I am triggering with software. But I still have to set external event to other than TI0B to get an interrupt. Thanks to everyone who commented here, I never would have found this without your help.
jdesouza
Posts: 1
Joined: Wed Dec 21, 2016 2:13 am

Re: Timer/Counter register B compare bug.

Wed Dec 21, 2016 5:15 pm

2 years later and I have encountered the same bug!
I tried setting a non-zero value to the EEVT bit in the CMR register, but the only thing that worked was to set XC0 which makes no sense to me. Anyways I wanted to thank you for the post...Would have taken me waaay longer to debug without it.

Return to “SAM7 ARM7TDMI MCU”

Who is online

Users browsing this forum: No registered users and 3 guests