Atmel website | ARM Community | AVR freaks | Technical Support
Banner
 FAQ •  Search •  Register •  Login 

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: RTT Interrupt not every 10sec
PostPosted: Thu Apr 07, 2011 3:26 pm 
Offline

Joined: Wed Aug 18, 2010 11:12 pm
Posts: 21
Hello,
I try to enable the RTT. I want to have an Interrupt every 10seconds.

I use a SAM7S512 with a 18,432Mhz crystal.

MAINF inside CKGR_MCFR is 1. So Slow Clock should be 1/16th of the Main Clock.
Is Main Clock = Crystal Clock or PLL-Clock / 2?

For now I thought Main Clock is Crystal Clock. So my Slow Clock would be 1.152Mhz.

I have set RTPRES to 0xE100. So I guess the timer increments with 20Hz. Alarm Value is than set to 200.

The PIT also gives an interrupt every 100µS. So Inside the ISR I first check if ALMS in the RTT_SR Register is set. Depending on this I toggle a LED.
If ALMS was set, I rewrite RTPRES to reset the counter.

The LED is flashing, but not with a 10 seconds period. It looks more like 2 or 3 seconds.
What did I do wrong.
Changing the Alarm Value did not make a difference (what I find very confusing)

Thanks for you help.

Regards.


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Thu Apr 07, 2011 9:49 pm 
Offline

Joined: Thu Dec 02, 2004 2:28 pm
Posts: 454
hello,
rtt is always fed by slow clock. slow clock is always driven by the internal rc oscillator and this oscillator is running with more or less 32khz.

regards
gerhard


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Fri Apr 08, 2011 11:03 am 
Offline

Joined: Wed Aug 18, 2010 11:12 pm
Posts: 21
So in this case I would need to set RTPRES to 0x8000 and the alarm Value to 10.

I have just tried this, but it makes no difference. LED's still flashing with about 2sec.

Is checking the RTT_SR not sufficient to determine the interrupt source?


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Fri Apr 08, 2011 11:17 am 
Offline

Joined: Wed Aug 18, 2010 11:12 pm
Posts: 21
When I disable the PIT nothing is happening. No more flashing LED. So something with the RTT Interrupt is not working.

I have configured the Interrupt source AT91C_ID_SYS like this.

AT91F_AIC_DisableIt(AT91C_BASE_AIC, AT91C_ID_SYS);
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SYS, PIT_INT_LEVEL,
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, PIT_ISR);
AT91F_PITC_CfgPMC();
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);

Then I've set RTPRES to 0x8000 and the alarm to 0x0A
AT91C_BASE_RTTC->RTTC_RTMR |= (0x8000);
AT91F_RTTSetAlarmValue(AT91C_BASE_RTTC,0x0A);

Then I enable the alarm INT.
AT91F_RTTSetAlarmINT(AT91C_BASE_RTTC);

In the ISR I check the RTT_SR and toggle the LED.

if(AT91C_BASE_RTTC->RTTC_RTSR && 0x01){
toggleIO(AT91C_BASE_PIOA, (1<<17));
AT91C_BASE_RTTC->RTTC_RTMR |= (0x8000);
return;
}

What did I forget?


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Fri Apr 08, 2011 2:50 pm 
Offline

Joined: Sat Oct 30, 2010 6:04 pm
Posts: 574
Wouldn't you always advance the current alarm by 10 at each alarm interrupt (ie RTAR = RTVR + 10)


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Fri Apr 08, 2011 3:44 pm 
Offline

Joined: Wed Aug 18, 2010 11:12 pm
Posts: 21
i've tried to count with my 100µs to 100 000 to get the 10sec period.

That roughly gives me the 10sec tick.
But I am confused about the PIV Value in the PIT_MR.
When I read (AT91C_BASE_PITC->PITC_PIMR&0xFFFFF) I get 0x012CD.
My Masterclock is 48. How does this work out?
In the documentation it says, that PIT counters work with Masterclock/16. So it would count with 3Mhz.

I would think, that the programmable reset PIV should be 0x00003 than?

Do I read it out wrong?


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Fri Apr 08, 2011 5:09 pm 
Offline

Joined: Sat Oct 30, 2010 6:04 pm
Posts: 574
20-bits at 3 MHz (48/16) is about 350 ms. ie Full Scale, Maximum Period
3 MHz has a period of 333.333 ns
100 us is 300 ticks @ 3 MHz (ie PIV=0x0012C)

Personally I'd not be interrupting at this rate, 1 ms, 100 ms, or 1 second would be much more realistic.

Use the RTT 1 second tick.

For you to have PIV=0x012CD, and 100 us tick coming for the PIT, you'd have to have ridiculously high MCK. Suggest you present a complete code example, with your PLL settings.


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Fri Apr 08, 2011 5:43 pm 
Offline

Joined: Wed Aug 18, 2010 11:12 pm
Posts: 21
I need both interrupts. One fast one, as a system tick. And the slow one to check a system state.

I see what was my mistake with the PIT.

So I still have the problem with the RTT. No System interrupt occurs once I disable the PIT.
Is it sufficient to set up the interrupt like written earlier and then to enable the RTT Alarm Int with writing RTTC_RTMR |= AT91C_RTTC_ALMIEN ?

Regards.


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Fri Apr 08, 2011 6:01 pm 
Offline

Joined: Wed Aug 18, 2010 11:12 pm
Posts: 21
Here is my lowlevelinit. I have taken this from Atmel.

//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------

#include "board.h"
#include "board_memories.h"
//#include <pmc/pmc.h>

//------------------------------------------------------------------------------
// Internal definitions
//------------------------------------------------------------------------------
// Startup time of main oscillator (in number of slow clock ticks).
#define BOARD_OSCOUNT (AT91C_CKGR_OSCOUNT & (0x40 << 8))

// USB PLL divisor value to obtain a 48MHz clock.
#define BOARD_USBDIV AT91C_CKGR_USBDIV_1

// PLL frequency range.
#define BOARD_CKGR_PLL AT91C_CKGR_OUT_0

// PLL startup time (in number of slow clock ticks).
#define BOARD_PLLCOUNT (16 << 8)

// PLL MUL value.
#define BOARD_MUL (AT91C_CKGR_MUL & (72 << 16))

// PLL DIV value.
#define BOARD_DIV (AT91C_CKGR_DIV & 14)

// Master clock prescaler value.
#define BOARD_PRESCALER AT91C_PMC_PRES_CLK_2

//------------------------------------------------------------------------------
// Internal functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Default spurious interrupt handler. Infinite loop.
//------------------------------------------------------------------------------
void defaultSpuriousHandler( void )
{
while (1);
}

//------------------------------------------------------------------------------
/// Default handler for fast interrupt requests. Infinite loop.
//------------------------------------------------------------------------------
void defaultFiqHandler( void )
{
while (1);
}

//------------------------------------------------------------------------------
/// Default handler for standard interrupt requests. Infinite loop.
//------------------------------------------------------------------------------
void defaultIrqHandler( void )
{
while (1);
}

//------------------------------------------------------------------------------
// Global Functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// Performs the low-level initialization of the chip. This includes EFC, master
/// clock, AIC & watchdog configuration, as well as memory remapping.
//------------------------------------------------------------------------------
void LowLevelInit(void)
{
unsigned char i;

// Set flash wait states in the EFC
// 48MHz = 1 wait state
#if defined(at91sam7s512)
AT91C_BASE_EFC0->EFC_FMR = AT91C_MC_FWS_1FWS;
AT91C_BASE_EFC1->EFC_FMR = AT91C_MC_FWS_1FWS;
#else
AT91C_BASE_MC->MC_FMR = AT91C_MC_FWS_1FWS;
#endif

// Initialize main oscillator
AT91C_BASE_PMC->PMC_MOR = BOARD_OSCOUNT | AT91C_CKGR_MOSCEN;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS));

// Initialize PLL at 96MHz (96.109) and USB clock to 48MHz
AT91C_BASE_PMC->PMC_PLLR = BOARD_USBDIV | BOARD_CKGR_PLL | BOARD_PLLCOUNT
| BOARD_MUL | BOARD_DIV;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK));

// Wait for the master clock if it was already initialized
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));

// Switch to slow clock + prescaler
AT91C_BASE_PMC->PMC_MCKR = BOARD_PRESCALER;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));

// Switch to fast clock + prescaler
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY));

// Initialize AIC
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
AT91C_BASE_AIC->AIC_SVR[0] = (unsigned int) defaultFiqHandler;
for (i = 1; i < 31; i++) {

AT91C_BASE_AIC->AIC_SVR[i] = (unsigned int) defaultIrqHandler;
}
AT91C_BASE_AIC->AIC_SPU = (unsigned int) defaultSpuriousHandler;

// Unstack nested interrupts
for (i = 0; i < 8 ; i++) {

AT91C_BASE_AIC->AIC_EOICR = 0;
}

// Enable Debug mode
AT91C_BASE_AIC->AIC_DCR = AT91C_AIC_DCR_PROT;

// Watchdog initialization
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;

// Remap the internal SRAM at 0x0
BOARD_RemapRam();

// Disable RTT and PIT interrupts (potential problem when program A
// configures RTT, then program B wants to use PIT only, interrupts
// from the RTT will still occur since they both use AT91C_ID_SYS)
AT91C_BASE_RTTC->RTTC_RTMR &= ~(AT91C_RTTC_ALMIEN | AT91C_RTTC_RTTINCIEN);
AT91C_BASE_PITC->PITC_PIMR &= ~AT91C_PITC_PITIEN;
}


My programmer provides this output
Master clock (estimated): 48054 KHz

0x12CD should be something like 16 ms?

Init of the PIT is done by

void AT91F_PITInit( AT91PS_PITC pPITC, unsigned int period, unsigned int pit_frequency)
{
pPITC->PITC_PIMR = period? (period * pit_frequency + 8) >> 4 : 0; // +8 to avoid %10 and /10
pPITC->PITC_PIMR |= AT91C_PITC_PITEN;
}

Period is 100 and frequency is 48.

0x12CD makes me assume that the value is not shifted?

I will try it with writing manually 0x12C


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Fri Apr 08, 2011 6:04 pm 
Offline

Joined: Wed Aug 18, 2010 11:12 pm
Posts: 21
by the way why can I not use BBCode?

I have seen the mistake. My Debugging wrote an extra D. :)

So it has been 0x12C all the time :(

Thanks for helping.

Any thoughts about my RTT approach?


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Sat Apr 09, 2011 2:38 am 
Offline

Joined: Sat Oct 30, 2010 6:04 pm
Posts: 574
Well it's certainly possible to have the PIT and RTT interrupting, it is complicated by the fact they all feed into the same OR gate, and generate a single SYS interrupt, and have pretty disparate clock sources. Edge sensitivity might be problematic.

As I see it, you might as well just use the high rate PIT for your 100us fast interrupt, and call your slow interrupt every 100,000 iterations for your 10 second tests. This would make for a significantly simpler interrupt handler, and dispatch routine.

The RTT alarm certainly works, your don't need to mess with the prescaler, you just advance the alarm register into the future.


Top
 Profile  
 
 Post subject: Re: RTT Interrupt not every 10sec
PostPosted: Tue Apr 12, 2011 6:17 pm 
Offline

Joined: Wed Aug 18, 2010 11:12 pm
Posts: 21
Thanks.
I will do so.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: