2018-12-07 07:57 PM
Hi,
I'm having a hard time configuring the system clock. It seems that I'm achieving 16MHz, but I want to run at full speed (216MHz). From what I'm seeing, the problem is that the System Clock Switch isn't changing to PLL. If I try to change bits 1:0 in the RCC_CFGR register, the status returns that the HSI is enabled.
RCC_BASE EQU 0x40023800
RCC_CR EQU RCC_BASE ;offset 0x00
RCC_CFGR EQU 0x40023808 ;offset 0x08
RCC_PLLCFGR EQU 0x40023804 ;offset 0x04
RCC_AHB1ENR EQU 0x40023830 ;offset 0x30
GPIOB_BASE EQU 0x40020400
GPIOB_MODER EQU GPIOB_BASE ;offset 0x00
GPIOB_ODR EQU 0x40020414 ;offset 0x14
GPIOB_EN EQU (1 << 1)
MODER0_OUT EQU (1 << 0)
PLLM EQU (4 << 0)
PLLN EQU (216 << 6)
PLLP EQU ((0 << 16) :OR: (0 << 17))
PLLQ EQU (9 << 24)
PLLHSE EQU (1 << 22)
AREA STM32, CODE, READONLY
ENTRY
EXPORT __main
__main
BL ENABLE_CLOCK
BL ENABLE_GPIOB
B CONTINUE
ENABLE_CLOCK
LDR R0, =RCC_CR
LDR R1, [R0]
ORR R1, #(1 << 18) ;HSE BYPASS
STR R1, [R0]
LDR R0, =RCC_CR
ORR R1, #(1 << 16) ;HSE ENABLE
STR R1, [R0]
HSE_READY LDR R0, =RCC_CR ;LOOP UNTIL READY
LDR R1, [R0]
AND R1, #(1 << 17)
MOVS R0, R1
BEQ HSE_READY
LDR R0, =RCC_PLLCFGR ;SET 216MHZ CLOCK
LDR R1, [R0]
ORR R1, #PLLM
ORR R1, #PLLN
ORR R1, #PLLP
ORR R1, #PLLQ
ORR R1, #PLLHSE
STR R1, [R0]
LDR R0, =RCC_CR
LDR R1, [R0]
ORR R1, #(1 << 24) ;PLL ON
STR R1, [R0]
PLL_LOCK LDR R0, =RCC_CR ;LOOP UNTIL READY
LDR R1, [R0]
AND R1, #(1 << 25)
MOVS R0, R1
BEQ PLL_LOCK
LDR R0, =RCC_CFGR
LDR R1, [R0]
ORR R1, #(2 << 0) ;PLL AS SYSCLK
STR R0, [R0]
;SYSCLK_STATUS LDR R0, =RCC_CFGR ;LOOP UNTIL READY
; LDR R1, [R0]
; AND R1, #(2 << 2)
; MOVS R0, R1
; BEQ SYSCLK_STATUS
BX LR
ENABLE_GPIOB
LDR R0, =RCC_AHB1ENR ;EN GPIO CLOCK
LDR R1, [R0]
ORR R1, #GPIOB_EN
STR R1, [R0]
LDR R0, =GPIOB_MODER ;SET OUTPUT
LDR R1, [R0]
ORR R1, #MODER0_OUT
STR R1, [R0]
BX LR
CONTINUE
LDR R1, =GPIOB_ODR ;OUTPUT DATA REGISTER
MOVW R0, #(1 << 0)
BLINK
LDR R2, =16000000
EOR R0, #(1 << 0)
STR R0, [R1]
BL DELAY
B BLINK
DELAY
SUBS R2, R2,#1
BNE DELAY
BX LR
ALIGN
END
I'm doing the following steps: set HSE to bypass, enable HSE, set PLLM, N, P and Q, enable PLL and finally (but not working) switching the system clock to PLL.
Solved! Go to Solution.
2018-12-08 01:43 PM
The flash needs to be configured to the number of wait-states the new clock will need.
2018-12-07 08:30 PM
Line 67 needs to be STR R1,[R0]
2018-12-07 09:49 PM
Oops, sorry about that. Finally got to pass the SWS verification. Thanks for the reply.
Also, corrected some mistakes regarding RCC_PLLCFGR configuration, like this
PLLMRST EQU ~(0x1F << 0)
PLLM EQU (4 << 0)
PLLNRST EQU ~(0xFF << 6)
PLLN EQU (216 << 6)
PLLP EQU ~((0 << 16) :OR: (0 << 17))
PLLQ EQU (9 << 24)
PLLQRST EQU ~(7 << 24)
PLLHSE EQU (1 << 22)
LDR R0,=RCC_PLLCFGR ;SET 216MHZ CLOCK
LDR R1, [R0]
AND R1, #PLLMRST
ORR R1, #PLLM
AND R1, #PLLNRST
ORR R1, #PLLN
AND R1, #PLLP
AND R1, #PLLQRST
ORR R1, #PLLQ
ORR R1, #PLLHSE
STR R1, [R0]
And now, instead of blinking the LED at 1sec rate (adjusting the delay), the processor ignores everything (like, skips all the code) and suddenly goes to SystemInit() when reaching the end of code
And does nothing more after this. Never saw anything like that, maybe I misconfigured something?
2018-12-08 01:44 AM
Now this is strange: you write assembler yet don't single-step in disassember window?
JW
2018-12-08 06:29 AM
That's not very efficient. The Assembler is not going to fold that, you need to condense it manually. You should be able to perform a single masking AND, followed by a single OR.
You understand __main != main right?
The Reset_Handler code typically calls SystemInit() prior to calling __main, which in normal implementation initializes the statics and then calls to main()
Perhaps uniquely name your routine, and call THAT from the Reset_Handler, and not the other components.
2018-12-08 12:05 PM
I renamed the main in the Reset_Handler. Now there shouldn't be any problem.
But, there's something wrong with the PLL switch, after the instruction to change the system clock, almost everything in the disassemble view turn MOVS r0,r0 and bugs.
I tried to reduce the clock below 216MHz, used 20 NOPs after changing the prescalers, but still nothing. The only way it worked was to divide the AHB by 8, but resulted in a clock less than 16MHz (from the blinking rate).
2018-12-08 12:09 PM
Sorry, I'm just new to these kind of things. I'm still learning what's important and the assembly itself. Didn't used the disassembler window before, but thanks for pointing that out.
2018-12-08 01:43 PM
The flash needs to be configured to the number of wait-states the new clock will need.
2018-12-08 04:52 PM
That was the solution! Thank you very much!
I guess a lot of things have to be considered when you move from C using vendor APIs...
I'll study carefully how my device works to anticipate this kind of situation.