cancel
Showing results for 
Search instead for 
Did you mean: 

STR9 96 MHz - how?

michael
Associate II
Posted on July 04, 2008 at 08:58

STR9 96 MHz - how?

7 REPLIES 7
michael
Associate II
Posted on May 17, 2011 at 09:51

Hello,

Maybe somebody from ST can explain this; I still haven't tried it on the device itself, but it would be refreshing to understand the actual requirements.

Trying to run a STR9 at 96 MHz, I stumbled upon the following guildelines:

KEIL (see

http://www.keil.com/support/docs/3306.htm

)

When you set the PLL post-divider value (PLL_PDIV) to 2 (hence: in order to run at 96 MHz), you must change the Clock Control Register (SCU_CLKCNTR) to the following:

* EMIRATIO: External Memory Interface Ratio fBCLK=HCLK/2

* FMISEL: Flash Memory Interface Clock Divider FMICLK=RCLK/2

ST (see

http://www.st.com/stonline/products/literature/an/13563.pdf

)

The Flash memory interface clock (FMICLK) should have the same frequency as the RCLK clock (96 MHz) this means no FMICLK dividers used

. As a result since Flash has a Sequential Burst read up to 96 MHz, we reduce execution time from there.

kais
Associate II
Posted on May 17, 2011 at 09:51

Hi,

You can configure CPU @ 96 and have FMICLK=RCLK/2 or FMICLK=RCLK : both configurations are correct.

However in the second one (FMICLK=RCLK=96MHZ) you have to insert 2 wait states in read operation from internal flash since Flash can reach 96MHZ as frequency only in sequential access.

For sure in the second config the execution from internal flash is much better.

Eris.

michael
Associate II
Posted on May 17, 2011 at 09:51

eris,

thanks for your reply. I have tried this - MCU at 48 MHz with the flash runhing at the same speed - after which I had to manualy erase the Flash (eval. board feature) to continue working because the settings of the SCU_CLKCNTR were ''invalid''. I might an older revision of the chip though.

Is this known to be a problem?

pm9341
Associate II
Posted on May 17, 2011 at 09:51

I am trying to flash write bank0 from bank1 and have the same problem. I't woks only with RCLK=48MHz, if not i get strange data written to flash.

I tryed RCLK=96MHz and FMICLK=RCLK/2 and don't get it to work.

kais
Associate II
Posted on May 17, 2011 at 09:51

Hi gays,

This limitation was known in RevB and RevD and already fixed in higher Revision devices:

Here below a detailed description of the limitation with proposed workarounds:

Flash memory erase and programming

Description of limitation in Rev B and Rev D

The Dual Bank Flash architecture in the STR91X supports the modification (erase or

programming) of one Flash bank while the CPU is fetching codes from the other bank.

This feature in the STR91x is functional only when the Flash bus clock (FMI Clock)

frequency is 25 MHz or lower. At higher clock frequency, the CPU may read incorrect code

or status from the Flash banks. The Flash modification problem affects both the dual banks

and the OTP sector.

Note: This limitation has no impact on the Flash erase or programming through the JTAG port.

Workarounds using Rev B and Rev D

1. Re-configure the STR91X clock when Flash erase or programming is needed. The

CPU clock (RCLK) must be configured to be 50 MHz or less, the RCLK is then divided

by 2 to provide a 25 MHz FMI clock. The CPU can return to full speed at 96 MHz after

the erase or programming operation is completed.

2. Another workaround is to copy the erase/programming routine from the Flash memory

to the SRAM; the CPU then branches to SRAM and executes the routine. The

advantage in this workaround is the CPU clock and the FMI clock can remain at 96

MHz during the Flash erase or programming.

Eris.

ranjeet_malhotra
Associate II
Posted on May 17, 2011 at 09:51

Hi,

We have seen similar issues while running code on STR910FAM32 (Rev G) silicon. The FMICLK = RCLK = 96MHz and waitstates is set 2. Every once in a while we see an issue when we are reading data from the secondary FLASH. There are instances when while the code is running from the SRAM, we try programming the secondary FLASH - and we see issues.

Any pointers to what could be wrong?

thanks.

ranjeet_malhotra
Associate II
Posted on May 17, 2011 at 09:51

Hi,

Here is the snippet of the code where this normally occurs. When an error occurs, the processor would hang. This issue only occurs when 'addr' points to start of the secondary FLASH. The other points to note:

1. Code has been tested on several hardware units to rule out a faulty hardware.

2. The Code works without any issues when 'addr' points to the area of the primary FLASH.

3. Size would be normally 4K or 8K.

To use the code we normally would program the first sector of the Seconday FLASH with a valid data - verify the data and then execute the operation described in the code snippet.

static unsigned long readtest(unsigned const char *addr, int size)

{

unsigned long l;

int i;

const unsigned char *data=addr;

unsigned long sum = 0;

for (i = 0; i < 128; i++)

{

//printf(''PMURRAY: %d, %p\n'', i, data);fflush(stdout);

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

l =(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<

l|=(((unsigned long)(*((data)++)))<< 8);

l|=(((unsigned long)(*((data)++))) );

sum+=l;

}

return sum;

}