ARM Clock System (ARM9)
First of all, it is important to be clear that when writing a program with a time series nature, it is important to know the time series diagram of its work first if you do not have any ideas. A time series diagram can clearly describe the entire process of its operation. Understanding the time series diagram will significantly improve the programming ideas.
The development board used in this study is: JZ2440
ARM version is: AMR9
1. Overview of clock framework
1. Frame structure
Before explaining how to programmatically change the clock frequency of the chip, figure out the ARM9 clock frame, which is shown in the S3C2440 chip manual.
Looking at the above frame diagram, we can see that the whole SOC is divided into three parts, which can be summarized as CPU part, AHB bus device part, APB bus device part. Moreover, AHB bus devices generally include LCD, Camera, Nand Flash, etc. APB bus devices generally include UART, IIC, SPI, GPIO, etc. The clock frequencies used in the three parts are different, so specific frequencies need to be set for specific parts.
2. Time Series Map Analysis
(1) First of all, you can see that when the CPU starts to power on, the system does not perform a reset operation immediately, but it takes some time before [t] starts the reset operation. The purpose of this is because when the system just powers on, the voltage is unstable, so it needs to delay for a while until the voltage is stable before the reset operation.
(2) The level changes of the OM[3:2] pin will be read in after the system reset operation, thus determining the crystal source selected by the system and the status of the PLL.
(3) After the CPU reset operation, the crystal oscillator starts to work and produces a clock signal, but the oscillation signal is not stable at this time, so it is necessary to delay a period of time for the crystal oscillation to output a stable oscillation signal. (4) The clock signal will then be locked, and there will be a lock time during which the clock signal will not occur.
(5) The CPU will run at the new clock frequency after the latch time has ended.
2. Programming Implementation
1. Diagram of clock signal distribution
2. Programming steps
(1) See in the schematic diagram that the two pins of OM[3:2] are in that state, and at the same time determine the frequency of the crystal vibration.
(2) Set LOCKTIME, or use the default value if you don't want to.
(3) Set up two registers, MPLLCON and UPLLCON, which determine MPLL and UPLL. MPLL is actually FCLK, UPLL is actually USB_CLK.
(4) Set up CLKDINVN, which mainly controls the size of HCLK and PCLK.
Notes: (1) When setting up MPLLCON, the chip manual will prompt you to set UPLLCON first if you want to set up MPLLCON
(2) If the value of HDIVN is not zero, the following code needs to be executed:
mrc p15,0,r0,c1,c0,0 orr r0,r0,#R1_nF:OR:R1_iA mcr p15,0,r0,c1,c0,0
Detailed explanations of these three lines will be analyzed in detail in the next topic.
3. Programming Instances
/**************************************** *Function: Set the working frequency of the chip with assembly language *Author: pengfei_M *Date: 2021.11.24 *****************************************/ .text .global _start _start: #define GPFCON 0x56000050 #define GPFDAT 0x56000054 #define UPLLCON 0x4C000008 #define MPLLCON 0x4C000004 #define CLKDIVN 0x4C000014 #define GPF_as_output_port 0x1500 ldr r0, = GPFCON ldr r1, = GPF_as_output_port str r1, [r0] //Set Clock// //Step 1: Set the clock source, you can see from the schematic diagram that OM[3:2] is the ground pin, so the external 12MHZ crystal vibration is selected. //LOCKTIME is set to the default value. //Step 2: Set up MPLLCON and UPLLCON registers ldr r4, =MPLLCON ldr r5, =UPLLCON //UPLL = 48mhz ldr r3, =((56<<12) | (2<<4) | (2<<0)) str r3, [r5] //MPLL = 400mhz ldr r3, =((92<<12) | (1<<4) | (1<<0)) str r3, [r4] //Step 3 Setting up CLKDIVN registers ldr r4, =CLKDIVN ldr r3, =0x5 str r3, [r4] //Set to Asynchronous Mode mrc p15,0,r0,c1,c0,0 orr r0,r0,#0xc0000000 mcr p15,0,r0,c1,c0,0 led_flash: bl led1_on bl delay bl led_off bl delay bl led2_on bl delay bl led_off bl delay bl led3_on bl delay bl led_off bl delay b led_flash led1_on: ldr r2, =0xef ldr r3, = GPFDAT str r2, [r3] mov pc, lr led2_on: ldr r2, =0xdf ldr r3, = GPFDAT str r2, [r3] mov pc, lr led3_on: ldr r2, = 0xbf ldr r3, = GPFDAT str r2, [r3] mov pc, lr led_off: ldr r2, = 0xff ldr r3, = GPFDAT str r2, [r3] mov pc, lr delay: mov r0, #0x40000 @ Note that this must not be written in the 0 loop below, otherwise it will become an infinite loop!! This is where we often make mistakes!! delay_loop: sub r0, r0, #1 mov r2, #0 cmp r0, r2 bne delay_loop mov pc, lr //Return to the place called