2014-02-07 08:25 PM
Could somebody help me to determine why my board is running at third of the speed. I am using emBlocks IDE and STM32F429I-Discovery_FW_V1.0.1 library. The loader code calls SystemInit (row 337 in system_stm32F4xx.c), which calls SetSysClock (row 470) executing rows 533-5 This confirms that the speed should be 180 MHz.
#if defined (STM
32
F
427
_
437
xx) || defined (STM
32
F
429
_
439
xx)
/* Enable the Over-drive to extend the clock frequency to 180 Mhz */
PWR->CR |= PWR_CR_ODEN;
while((PWR->CSR & PWR_CSR_ODRDY) ==
0
)
{
}
PWR->CR |= PWR_CR_ODSWEN;
while((PWR->CSR & PWR_CSR_ODSWRDY) ==
0
)
{
}
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_
5
WS;
#endif
/* STM32F427_437x || STM32F429_439xx */
At micro level I am doing fast pulses that should be around 10 nanosecond long, but are 35 nanosecond long as shown in oscilloscope.
This pulse train is generated with the following code
#include <stm
32
f
4
xx.h>
#include <stm
32
f
4
_init.h>
int main(void)
{
RCC->AHB
1
ENR |= RCC_AHB
1
ENR_GPIOCEN; // Enable GPIOC clock
GPIOC->MODER = GPIO_Mode_OUT <<(
2
*
13
); // Configure PC
13
GPIOC->OTYPER = GPIO_OType_PP <<(
2
*
13
); // ignore other pins
GPIOC->OSPEEDR = GPIO_Speed_
100
MHz <<(
2
*
13
);
GPIOC->PUPDR = GPIO_PuPd_NOPULL <<(
2
*
13
);
while (
1
) {
GPIOC->BSRRL = GPIO_BSRR_BS_
13
; // Set PC
13
GPIOC->BSRRH = GPIO_BSRR_BS_
13
; // Clear PC
13
GPIOC->BSRRL = GPIO_BSRR_BS_
13
;
GPIOC->BSRRH = GPIO_BSRR_BS_
13
;
GPIOC->BSRRL = GPIO_BSRR_BS_
13
;
GPIOC->BSRRH = GPIO_BSRR_BS_
13
;
GPIOC->BSRRL = GPIO_BSRR_BS_
13
;
GPIOC->BSRRH = GPIO_BSRR_BS_
13
;
GPIOC->BSRRL = GPIO_BSRR_BS_
13
;
GPIOC->BSRRH = GPIO_BSRR_BS_
13
;
}
}
Assembly code for the while(1) loop
080002FE strh r3, [r2, #24]
08000300 strh r3, [r2, #26]
08000302 strh r3, [r2, #24]
08000304 strh r3, [r2, #26]
08000306 strh r3, [r2, #24]
08000308 strh r3, [r2, #26]
0800030A strh r3, [r2, #24]
0800030C strh r3, [r2, #26]
0800030E strh r3, [r2, #24]
08000310 strh r3, [r2, #26]
08000312 b.n 0x80002fe <
main
+50>
At macro level, I am trying to toggle a pulse with 1000 Hz frequency. The expected pulse width is 1000 microseconds, but oscilloscope shows 3222 microsecond long pulses.
This pulse train was created with the following code.
#include <stm
32
f
4
xx.h>
#include <stm
32
f
4
_init.h>
#def
ine oneMilliSecond
180
*
1000
int main(void)
{
uint
32
_t triggerLimit=
0
;
uint
32
_t loopCount=
0
;
RCC->AHB
1
ENR |= RCC_AHB
1
ENR_GPIOCEN; // Enable GPIOC clock
GPIOC->MODER = GPIO_Mode_OUT <<(
2
*
13
); // Configure PC
13
GPIOC->OTYPER = GPIO_OType_PP <<(
2
*
13
); // ignore other pins
GPIOC->OSPEEDR = GPIO_Speed_
100
MHz <<(
2
*
13
);
GPIOC->PUPDR = GPIO_PuPd_NOPULL <<(
2
*
13
);
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // Enable core debugger for tracing
DWT->CYCCNT =
0
; // Reset debugger trace
counter
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; // Enable cycle
counter
while (
1
) {
if (DWT->CYCCNT > triggerLimit) {
triggerLimit += oneMilliSecond;
loopCount++;
if (loopCount &
1
) {
GPIOC->BSRRL = GPIO_BSRR_BS_
13
; // Set PC
13
} else {
GPIOC->BSRRH = GPIO_BSRR_BS_
13
; // Clear PC
13
}
}
}
}
The assembly code for the infinite loop is
08000320 ldr r3, [r1, #4]
08000322 cmp r2, r3
08000324 bcs.n 0x8000320 <
main
+84>
08000326 adds r0, #1
08000328 lsls r3, r0, #31
0800032A add.w r2, r2, #179200 ; 0x2bc00
0800032E add.w r2, r2, #800 ; 0x320
08000332 ite mi
08000334 strhmi r4, [r5, #24]
08000336 strhpl r4, [r5, #26]
08000338 b.n 0x8000320 <
main
+84>
Note how the 1 millisecond value (180,000) is implemented as 179,200 + 800.
I have observed similar results with the SysTick_Handler configured by SysTick_Config.
#unexpected-low-performance
2014-02-08 05:19 AM
If you want to inspect internal clocks, would suggest using the MCOx pins and routing the signals, or fractions thereof, to them.
As for your problem it sounds like you have the PLL settings for a device using a 25 MHz crystal, not an 8 MHz one. Check those in system_stm32f4xx.c, and the define for HSE_VALUE within the project.2014-02-08 01:34 PM
Clive,
Thanks for a quick response. I am still a newbie in STM32F429 Disco usage and could not translate your instructions into corrective actions. 1) I have to admit that I don't know what the MCOx pins are 2) I don't understand the statement ''using the MCOx pins and routing the signals, or fractions thereof, to them.'' 3) I am using the unmodified standard library from ST for the F429 Disco board. What could be the reason, why the default setting is not providing the assumed 180 MHz speed 4) Does this mean that in my project setting I need to have a HSE_VALUE ((uint32_t)8000000) symbol definition in the project defintion files. I did try that, but it didn't allow the project building. 5) Should I modify some of the lines in the system_stm32f4xx.c file. Which lines and which way. Sorry for these trivial questions. They are easy for you but quite difficult for me.2014-02-08 01:48 PM
I did add the HSE_VALUE into main.c file as shown below to enable compilation.
#def
ine HSE_VALUE ((uint
32
_t)
8000000
#include <stm
32
f
4
xx.h>
#include <stm
32
f
4
_init.h>
#def
ine oneMilliSecond
180
*
1000
int main(void)
THen I added breakpoint on every line where HSE_VALUE is used. None of those lines were executed. That means that the clock speed issue was not resolved.
2014-02-08 01:59 PM
I suspect you are using the STM32F429I-Discovery_FW_V1.0.0\Libraries\CMSIS\Device\ST\STM32F4xx\Source\Templates\system_stm32f4xx.c file, which presupposes that the board has a 25 MHz crystal, and has an PLL_M value of 25 rather than 8. The STM32F429I-DISCO board has a 8 MHz crystal. A more appropriate file might be found in one of the project files for the board, or the template.
STM32F429I-Discovery_FW_V1.0.0\Projects\Peripheral_Examples\ADC_DMA\system_stm32f4xx.c STM32F429I-Discovery_FW_V1.0.0\Projects\Template\system_stm32f4xx.c The MCO pins MCO1 (PA8) and MCO2 can output internal frequencies up to 100 MHz (pin driver limit), for 180 MHz you'd have to select the Div2 prescaler to get it out, the HSE and HSI you could get out at Div1, ie Fractional clocks 1/2, 1/3, 1/4, 1/5 Thehttp://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf
would be a good place to start. pg 156, 163, 1642014-02-08 02:05 PM
HSE_VALUE needs to be a project wide define, passed in by the compiler ideally
The file you need to get correct is the system_stm32f4xx.c*=============================================================================
* Supported STM32F42xxx/43xxx devices
*-----------------------------------------------------------------------------
* System Clock source | PLL (HSE)
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 180000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 180000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 4
*-----------------------------------------------------------------------------
* APB2 Prescaler | 2
*-----------------------------------------------------------------------------
* HSE Frequency(Hz) | 25000000
*-----------------------------------------------------------------------------
* PLL_M | 25
*-----------------------------------------------------------------------------
* PLL_N | 360
*-----------------------------------------------------------------------------
* PLL_P | 2
*-----------------------------------------------------------------------------
* PLL_Q | 7
*-----------------------------------------------------------------------------
* PLLI2S_N | NA
*-----------------------------------------------------------------------------
* PLLI2S_R | NA
*-----------------------------------------------------------------------------
* I2S input clock | NA
*-----------------------------------------------------------------------------
* VDD(V) | 3.3
*-----------------------------------------------------------------------------
* Main regulator output voltage | Scale1 mode
*-----------------------------------------------------------------------------
* Flash Latency(WS) | 5
*-----------------------------------------------------------------------------
* Prefetch Buffer | ON
*-----------------------------------------------------------------------------
* Instruction cache | ON
*-----------------------------------------------------------------------------
* Data cache | ON
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Disabled
* SDIO and RNG clock |
*-----------------------------------------------------------------------------
*=============================================================================
..
/************************* PLL Parameters *************************************/
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
#define PLL_M 25
/* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */
#define PLL_Q 7
Not 25 MHz, board uses 8 MHz, must adjust math in PLL to resolve that. PLL_M needs to be 8
2014-02-08 10:09 PM
Thanks Clive,
I got it working now. Theonly
proper working combination was to takesystem_stm32f4xx.h
from STM32F429I-Discovery_FW_V1.0.1\Libraries\CMSIS\Device\ST\STM32F4xx\Includesystem_stm32f4xx.c
from STM32F429I-Discovery_FW_V1.0.1\Projects\Template0
even when the version STM32F429I-Discovery_FW_V1.0.1
has been available for several months.2014-02-09 01:01 PM
V1.0.0 happened to be a tree I had to hand. The files are materially the same, and in the same locations, the point being if you used the one in the Libraries tree it would have the wrong settings for the DISCO board. As I first indicated it's the system_stm32f4xx.c the file that controls the settings which you likely had issues with.
The majority of ST's profession boards use the 25 MHz crystal and have Ethernet support.The appropriate place for board/project specific system settings is a file stored in the project directory, as done by the template project, and the examples.The ADC probably uses 144 MHz related to ADC clocking maximums, as project appropriate. The USB example likely use 168 MHz clocks, so they can get a 48 MHz USB clock.2014-02-09 08:59 PM
Thanks Clive,
As a newbie, I didn't realize that system_stm32f4xx.c isnot
a board specific system file, but a starting point for project specific modifications. I guess that there is no shortcut to learn the STM specific design and development style by doing the mistakes and learning from those. In ideal world, I wanted to learn from the mistakes done by the newbie before me.