EmbeddedRelated.com
Forums

Reset Behavior

Started by Nick Howes January 26, 2009
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nick Howes wrote:
> --- In A..., "Nick Howes" wrote:
>> --- In A..., "jellybean10025" wrote:
>>
>>> while ((pRSTC->RSTC_RSR) & C_RSTC_SRCMP)
>> Well yeah, that makes perfect sense - I need to wait for the reset process to
>> complete so that it doesn't use the wrong vectors.
>
> Well it seemed like this was the answer, but it hasn't solved my problem. :(
>

I never thought your problem was so trivial so I never asked but are you enabling
user reset before resetting? I know your reset is working normally but just in case...

Caglar

> - Nick

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iEYEARECAAYFAkl+KkYACgkQ/nL+S5dojegK+ACgp9FEoPyPA3RXZvUWA+OCG7j1
acMAoJgnYy1bG1qcECTNirPkY4CQJJSB
As
-----END PGP SIGNATURE-----

--- In A..., Yusuf Caglar AKYUZ wrote:
>
> I never thought your problem was so trivial so I never asked but are you enabling
> user reset before resetting? I know your reset is working normally but just in case...

Hi Caglar,

User reset is not enabled.

More info:
This bit of code works:
AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24) | AT91C_RSTC_PERRST |
AT91C_RSTC_EXTRST); //reset the peripherals and remap
while ((AT91C_BASE_RSTC->RSTC_RSR) & AT91C_RSTC_SRCMP); //wait for reset to
complete
((void(*)(void))0x00100000)(); //transfer control to reset vector in Flash (0x00100000)

but if I use the following, it fails:
AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24) | AT91C_RSTC_PERRST |
AT91C_RSTC_EXTRST); //reset the peripherals and remap
while ((AT91C_BASE_RSTC->RSTC_RSR) & AT91C_RSTC_SRCMP); //wait for reset to
complete
AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24) | AT91C_RSTC_PROCRST);

I guess I can use the code that works, but I would dearly love to understand what is
happening.

- Nick
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Nick Howes wrote:
> More info:
> This bit of code works:
> AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24) | AT91C_RSTC_PERRST |
> AT91C_RSTC_EXTRST); //reset the peripherals and remap
> while ((AT91C_BASE_RSTC->RSTC_RSR) & AT91C_RSTC_SRCMP); //wait for reset to
> complete
> ((void(*)(void))0x00100000)(); //transfer control to reset vector in Flash (0x00100000)
>
> but if I use the following, it fails:

can you try this one:

> AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24) | AT91C_RSTC_PERRST |
> AT91C_RSTC_EXTRST); //reset the peripherals and remap
> while ((AT91C_BASE_RSTC->RSTC_RSR) & AT91C_RSTC_SRCMP); //wait for reset to
> complete
> AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24) | AT91C_RSTC_PROCRST);
>

as:

AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24)
| AT91C_RSTC_PERRST
| AT91C_RSTC_EXTRST
| AT91C_RSTC_PROCRST);
while ((AT91C_BASE_RSTC->RSTC_RSR) & AT91C_RSTC_SRCMP);

> I guess I can use the code that works, but I would dearly love to understand what is
> happening.
>
> - Nick

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iEYEARECAAYFAkl+QaEACgkQ/nL+S5dojeiglwCeJW380eVq4keynYLPbNVbHhTH
epwAnRuReaEbwYTslEG+0bRVaLab1vTL
=DYC8
-----END PGP SIGNATURE-----

--- In A..., Yusuf Caglar AKYUZ wrote:

> can you try:
>
> AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24)
> | AT91C_RSTC_PERRST
> | AT91C_RSTC_EXTRST
> | AT91C_RSTC_PROCRST);
> while ((AT91C_BASE_RSTC->RSTC_RSR) & AT91C_RSTC_SRCMP);

Yes, I've tried that and it doesn't work. And I've tried various similar sequences - e.g.
separating the PERRST from the PROCRST, going into an endless loop after the PROCRST, etc.

- Nick
>From the working and non working code, looks like the
difference is only the line that involves the PROCRST
define. Sounds like PROCRST is a processor reset and
might clear the program counter(I'm not sure on this).
If it does clear the PC, then the code execution would
basically go back to the start of your program causing
an infinite loop...

--- Nick Howes wrote:

> --- In A..., Yusuf Caglar AKYUZ
> wrote:
>
> > can you try:
> >
> > AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24)
> > | AT91C_RSTC_PERRST
> > | AT91C_RSTC_EXTRST
> > | AT91C_RSTC_PROCRST);
> > while ((AT91C_BASE_RSTC->RSTC_RSR) &
> AT91C_RSTC_SRCMP);
>
> Yes, I've tried that and it doesn't work. And I've
> tried various similar sequences - e.g.
> separating the PERRST from the PROCRST, going into
> an endless loop after the PROCRST, etc.
>
> - Nick

Can you please post your LowLevelInit sequence ?

Eric.
----- Original Message -----
From: Nick Howes
To: A...
Sent: Tuesday, January 27, 2009 12:24 AM
Subject: [AT91SAM] Re: Reset Behavior
--- In A..., Yusuf Caglar AKYUZ wrote:

> can you try:
>
> AT91C_BASE_RSTC->RSTC_RCR = ((0xA5 << 24)
> | AT91C_RSTC_PERRST
> | AT91C_RSTC_EXTRST
> | AT91C_RSTC_PROCRST);
> while ((AT91C_BASE_RSTC->RSTC_RSR) & AT91C_RSTC_SRCMP);

Yes, I've tried that and it doesn't work. And I've tried various similar sequences - e.g.
separating the PERRST from the PROCRST, going into an endless loop after the PROCRST, etc.

- Nick
--- In A..., "Eric Pasquier" wrote:

> Can you please post your LowLevelInit sequence ?

Hi Eric,

Is this is what you are asking for?

#define FMCN_PLL_1_0_US 48 //48 cycles for 1us
#define FMCN_PLL_1_5_US 72 //72 cycles for 1.5us
#define MOR_OSC_CNT 8 //1.52 - 2.9 ms depending on SLCK accuracy
#define PLLR_DIV 5 //18.432MHz 5 = 3.6864MHz
#define PLLR_MUL 25 //3.6864MHz * 26 = 95.8464MHz
#define PLLR_PLL_CNT 28 //this value comes from the Atmel sample file
(number of slow clocks before LOCK bit set)
#define PLLR_USB 1 //1 means divide-by-two; 95.8464MHz 2 =
47.9232MHz (48MHz - 0.16%)

void base_init() {

AT91C_BASE_MC->MC_FMR = (FMCN_PLL_1_5_US << 16) | AT91C_MC_FWS_1FWS;
//setup flash

AT91C_BASE_PMC->PMC_MOR = (MOR_OSC_CNT << 8) | AT91C_CKGR_MOSCEN;
//enable Main Oscillator
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)); //wait for osc startup

AT91C_BASE_PMC->PMC_PLLR = (PLLR_USB << 28) | (PLLR_MUL << 16) |
(PLLR_PLL_CNT << 8) | PLLR_DIV; //setup PLL
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK)); //wait for PLL startup

AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2; //set MCK divider to 2
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); //wait for clock to be
ready

AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLL_CLK |
AT91C_PMC_PRES_CLK_2; //set MCK source to PLL
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); //wait for clock to be
ready

}

(I tried waiting for AT91C_PMC_MCKRDY at the beginning of this routine, but it made no
difference.)
thx, Nick

Can you please test this configuration :
- - - (ok)
pPMC->PMC_PLLR = ( - - - ) (ok)

// Wait the startup time (until PMC Status register LOCK bit is set)
while(!(pPMC->PMC_SR & AT91C_PMC_LOCK));

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

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

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

// Initialize AIC
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
Eric
----- Original Message -----
From: Nick Howes
To: A...
Sent: Tuesday, January 27, 2009 2:15 PM
Subject: [AT91SAM] Re: Reset Behavior
--- In A..., "Eric Pasquier" wrote:

> Can you please post your LowLevelInit sequence ?

Hi Eric,

Is this is what you are asking for?

#define FMCN_PLL_1_0_US 48 //48 cycles for 1us
#define FMCN_PLL_1_5_US 72 //72 cycles for 1.5us
#define MOR_OSC_CNT 8 //1.52 - 2.9 ms depending on SLCK accuracy
#define PLLR_DIV 5 //18.432MHz 5 = 3.6864MHz
#define PLLR_MUL 25 //3.6864MHz * 26 = 95.8464MHz
#define PLLR_PLL_CNT 28 //this value comes from the Atmel sample file
(number of slow clocks before LOCK bit set)
#define PLLR_USB 1 //1 means divide-by-two; 95.8464MHz 2 47.9232MHz (48MHz - 0.16%)

void base_init() {

AT91C_BASE_MC->MC_FMR = (FMCN_PLL_1_5_US << 16) | AT91C_MC_FWS_1FWS;
//setup flash

AT91C_BASE_PMC->PMC_MOR = (MOR_OSC_CNT << 8) | AT91C_CKGR_MOSCEN;
//enable Main Oscillator
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)); //wait for osc startup

AT91C_BASE_PMC->PMC_PLLR = (PLLR_USB << 28) | (PLLR_MUL << 16) |
(PLLR_PLL_CNT << 8) | PLLR_DIV; //setup PLL
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK)); //wait for PLL startup

AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2; //set MCK divider to 2
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); //wait for clock to be
ready

AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLL_CLK |
AT91C_PMC_PRES_CLK_2; //set MCK source to PLL
while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); //wait for clock to be
ready

}

(I tried waiting for AT91C_PMC_MCKRDY at the beginning of this routine, but it made no
difference.)

thx, Nick
--- In A..., "Eric Pasquier" wrote:

> Can you please test this configuration :

Hi Eric,

I tried the changes you suggested (including the AIC initialization stuff in your separate e-
mail) - it behaved in the same way.

- Nick
Then I think you need to be looking elsewhere as Eric is suggesting.

The code I posted absolutely works. It is in thousands of our
production units and we do software updates frequently.

There must be something else going on here.

PS: We strip off the "AT91" to keep the typing down, but otherwise
don't touch the header files.

--- In A..., "Nick Howes" wrote:
>
> --- In A..., "Nick Howes" wrote:
> >
> > --- In A..., "jellybean10025"
wrote:
> >
> > > while ((pRSTC->RSTC_RSR) & C_RSTC_SRCMP)
> >
> > Well yeah, that makes perfect sense - I need to wait for the reset
process to
> > complete so that it doesn't use the wrong vectors.
>
> Well it seemed like this was the answer, but it hasn't solved my
problem. :(
>
> - Nick
>