EmbeddedRelated.com
Forums

Timer0 interrupts..

Started by strong_arm7s April 11, 2005

Hello,
I am using the ThreadX OS and tring to get it to work with the
AT91SAM7S-EK eval kit and IAR Embeded Workbench.
Much of last week was conversing with IAR and Expresslogic in tryting
to get a file compiled and run in the flash of the AT91SAM7S.
We have that going, however ThreadX requires Timer0 of the TC to run
and cause an interrupt. If timer0 does not run then the Timers and a
lot of other ThreadX features don't run.
The trouble is the demo from ExpressLogic runs of the AT91EB01 eval
board. I have made lots of changes to the startup .s79 (assembler)
file that came with the EB01 in order to get it to work with the
SAM7S, but the timer interrupt is still not running.
I can email anyone my startup file if they feel they can help me out
here.
Has anybody else done this??
Any help would be appreciated.
Thanks.
Andrew


Hi Andrew,
 
> and cause an interrupt.  If timer0 does not run then the Timers and a
> lot of other ThreadX features don't run.
> The trouble is the demo from ExpressLogic runs of the AT91EB01 eval
> board.  I have made lots of changes to the startup .s79 (assembler)
> file that came with the EB01 in order to get it to work with the
> SAM7S, but the timer interrupt is still not running.
> I can email anyone my startup file if they feel they can help me out
Don't know why you're concerned with startup file, I would prefer that the C
init code at start of main() takes care of this.
 
Timer 0 is not a big drama to use INTs on, just make sure you have the AIC set up
properly.
I've pasted in some snippet code I use to init TC0 with SAM7S-EK board.
You just need the functions mask_isr() and unmask_isr(), these are slightly changed
CrossWorks functions to enable and disable individual INTs.
set_irq_isr() just sets up the AIC given the proper Per. ID # , trigger level, priority etc.
Then you just need to define TIMER_TICK to a value that suits your MCLK and INT interval you need.
I just use my own startup file that exports the PLL settings, calcs MCLK at compile time, and adjusts
the constants to yield 1 mS ticks.
If you follow this sequence I use, it should work hunkey dory.
 
PS : You might need to define the constants for Timer use, but you should already have them if you
ported it from an EB01.
 
Good luck !
 
.................
 
void sys_init (void)
{
// enable nRST pin
RSTC_MR = KEY+URSTEN;        
// Set spurious vector
set_irq_isr (SPU_VECTOR, 1, ISR_TRIGGER_LOW_LEVEL, spurious_irq_handler, 0);
 
// Set up PIO
PIOA_PER = SW1 | SW2 | SW3 | SW4 | 0x0F | RTS;         // SW 1-4 + LEDs
PIOA_ODR = SW1 | SW2 | SW3 | SW4;                          // output disable - switches
PIOA_OER = RTS + 0x0F;                                              // Leds output En
PIOA_SODR = 0x0F;                                                     // LEDs off
PIOA_OWER = 0x0F;                                                    // allow direct write to PIO_ODSR
 
// Set up PIO Interrupts
MC_PCER = 1<< PIOA_PID;                                         // Enable PIO clocks.
mask_isr (PIOA_PID);
set_irq_isr (PIOA_PID, 1, ISR_TRIGGER_LOW_LEVEL, event_irq_handler, 0);
AIC_ICCR = 1 << PIOA_PID;
PIOA_ISR;                                                                 // Clear the pending/spurious startup flags
 
// And now Enable PIO change INTs
unmask_isr (PIOA_PID);
 
// Set up Timer0 interrupts
mask_isr (TC0_PID);
set_irq_isr (TC0_PID, 1, ISR_TRIGGER_LOW_LEVEL, timer0_irq_handler, 0);
 
//Set up timer
PMC_PCER |= 1 << TC0_PID;                                     // Enable T0 peripheral clock
TC0_CCR = TC_CLKDIS;                                             // Disable TC0 clock first
TC0_IDR = 0xFFFFFFFF;                                             // Disable all TC0 INTs
TC0_CMR = TC_EEVT_XC0+TC_WAVESEL10+TC_WAVE+     // MCLK/1024
                 TC_CLKS_MCK1024;                                        // Interrupts on RC compare, reset
                 TC0_IER = TC_CPCS;                                      // Int on RC compare
TC0_RC = TIMER_TICK;                                            // to yield 1 mS INTs TC0
TC0_CCR = TC_CLKEN | TC_SWTRG;                         // Enable clock / start Timer
 
// Enable TCO Interrupts
unmask_isr (TC0_PID);
 
.........
 
// Global enable INTs
enable_interrupts();
 
........
 
 
 
-- Kris
 


BTW Andrew,
 
> SAM7S, but the timer interrupt is still not running.
> I can email anyone my startup file if they feel they can help me out
> here.
> Has anybody else done this??
> Any help would be appreciated.
Did you use TC_RB by any chance ?
I posted this on at91.com quite some time ago, and at the kickoff of this group
as well on Wed 2 Feb 2005, copy below :
 
Subject : No compare Interrupts for TC_RB
--------------
 
I could NOT get compare interrupts on TC_RB and tested with
WAVE = 1, and tried with WAVESEL = 00 or WAVESEL = 10.
 
Soon I solved the problem :
 
I set it up to output toggle the TIOA and TIOB signals on PA0,PA1 and same drama,
no RB compare toggle output.........
 
Then I saw the EEVT bits in TC_CMR !!! (External Event trigger)
The default is 00 - or TIOB event, TIOB as commented becomes an input.
That fixes that for the output unit...  Could this affect RB compare ?
Surely not ?
 
I added a simple definition for XC1 as EEVT in TC_CMR (instead of default TIOB)
and the interrupt RB compare now works !!!!
 
I DON'T see why the EEVT bits should affect the normal RB compare interrupt,
but that's how it turned out ...
 
I hope this saves some of you the intiial trouble I had with RB compare INTs for TC.
 
B regards
Kris
 



This code is called right at the start of Main()
The way ThreadX works is that the only function in Main is
TX_KERNEL_ENTER and the first function called in that in
TX_initialize which calls this initial part of assembler code that
they wrote for the EB01 board and I have modified for the 91SAM7S.
In answer to your last question we are using TC, not B. I wonder if
the same thing has to be done. I am digesting what you put Kris,
thanks a bunch..
Andrew

SOURCE_MODE_12 DEFINE 0xFFFFF030 ;SMR[ID_TC0]
SOURCE_VECTOR_12 DEFINE 0xFFFFF0B0 ;SVR[ID_TC0]

AIC_IVR DEFINE 0xFFFFF100 ; interrupt vector register
AIC_IECR DEFINE 0xFFFFF120 ; interrupt enable register
AIC_IDCR DEFINE 0xFFFFF124
AIC_ICCR DEFINE 0xFFFFF128
AIC_ISCR DEFINE 0xFFFFF12C
AIC_EOICR DEFINE 0xFFFFF130

MC_FMR DEFINE 0xFFFFFF60 ; Address of FMC

PMC_PCER DEFINE 0xFFFFFC10
PMC_MOR DEFINE 0xFFFFFC20
PMC_PLLR DEFINE 0xFFFFFC2C
PMC_MCKR DEFINE 0xFFFFFC30

TC_CCR DEFINE 0xFFFA0000 ;Timer Channel Control register
TC_CMR DEFINE 0xFFFA0004 ;Timer Chanel Mode register
TC_CV DEFINE 0xFFFA0010 ;Timer Counter Value register
TC_RC DEFINE 0xFFFA001C ;Timer Register C
TC_SR DEFINE 0xFFFA0020 ;Timer Status register
TC_IER DEFINE 0xFFFA0024 ;Interrupt Enable register
TC_IDR DEFINE 0xFFFA0028 ;Interrupt Disable register
TC_IMR DEFINE 0xFFFA002C ;Interrupt Mask register

TIMER0_IRQ_MODE DEFINE 0x21 ; Edge Triggered IRQ mode - EB01
TIMER0_BIT DEFINE 0x1000
TIMER0_CPCS DEFINE 0x10
TIMER0_MODE DEFINE 0xC000
TIMER0_COUNT_VALUE DEFINE 0xFFFF ; Register C count/compare value
TIMER0_DISABLE DEFINE 0x0002 ; Timer 0 disable value
TIMER0_ENABLE DEFINE 0x0001 ; Timer 0 Enable value
TIMER0_SYNC DEFINE 0x0004 ; Timer 0 Sync (start) value

; Code called at the start of Main()

LDR r2,=PMC_PCER
LDR r1,=TIMER0_BIT
STR r1, [r2] ; Enable the clk

LDR r2,=AIC_IDCR
LDR r1,=TIMER0_BIT
STR r1, [r2]

LDR r2,=SOURCE_VECTOR_12
LDR r1,=__tx_timer_handler ; add of actual timer vector
STR r1, [r2] ; Setup timer vector
LDR r2,=SOURCE_MODE_12
LDR r1,=TIMER0_IRQ_MODE ; Build mode value
STR r1, [r2]

LDR r2,=AIC_ICCR
LDR r1,=TIMER0_BIT
STR r1, [r2]

LDR r2,=AIC_IECR
LDR r1,=TIMER0_BIT
STR r1, [r2]

LDR r2,=TC_CCR
LDR r1,=TIMER0_DISABLE
STR r1, [r2]

LDR r2,=TC_IDR
MOV r1,#0xFF
STR r1, [r2]

LDR r2,=TC_SR
LDR r1, [r2] ; Read status Reg - Clear Status

LDR r2,=TC_CMR
LDR r1,=TIMER0_SYNC
STR r1, [r2]

LDR r2,=TC_IMR
LDR r1,=TIMER0_CPCS
STR r1, [r2]

LDR r2,=TC_RC
LDR r1,=TIMER0_COUNT_VALUE ; Build count/compare value
STR r1, [r2] ; Setup timer register C

LDR r2,=TC_IER
LDR r1,=TIMER0_CPCS
STR r1, [r2] ; Enable timer0 interrupts

LDR r2,=TC_CCR
LDR r1,=TIMER0_ENABLE
STR r1, [r2] ; Enable the timer
LDR r1,=TIMER0_SYNC ; Build timer sync value
STR r1, [r2] ; Start the timer running!