2008-07-03 11:58 PM
2011-05-17 12:51 AM
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 ) 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/2ST (see ) 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.2011-05-17 12:51 AM
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.2011-05-17 12:51 AM
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?2011-05-17 12:51 AM
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.2011-05-17 12:51 AM
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.2011-05-17 12:51 AM
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.2011-05-17 12:51 AM
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; }