In fact, the IROM code of Exynos 4412 has already set the PLL. We can print out the PLL register values set by IROM through the serial port. These values are printed out like this (excerpted from "Complete Manual of Embedded Linux System Development_Based on 4412__Volume 1" by Teacher Wei Dongshan):
CLK_SRC_CPU = 0x01000001
CLK_DIV_DMC0 = 0x00111713
CLK_DIV_DMC1 = 0x01011171
CLK_SRC_TOP0 = 0x01110000
CLK_SRC_TOP1 = 0x00001000
CLK_DIV_TOP = 0x00015470
CLK_SRC_LEFTBUS = 0x00000001
CLK_DIV_LEFTBUS = 0x00000013
CLK_SRC_RIGHTBUS = 0x00000001
CLK_DIV_RIGHTBUS = 0x00000013
APLL_LOCK = 0x00000960
MPLL_LOCK = 0x00000000
EPLL_LOCK = 0x00000FFF
VPLL_LOCK = 0x00000FFF
CLK_DIV_CPU0 = 0x00773730
CLK_DIV_CPU1 = 0x00000077
APLL_CON1 = 0x00003800
APLL_CON0 = 0xA0640301
MPLL_CON1 = 0x00003800
MPLL_CON0 = 0xA0640301
EPLL_CON2 = 0x00000080
EPLL_CON1 = 0x66010000
EPLL_CON0 = 0x00600302
VPLL_CON2 = 0x00000080
VPLL_CON1 = 0x66016000
VPLL_CON0 = 0x006F0302
CLK_SRC_CPU = 0x01000001
CLK_SRC_DMC = 0x00111000
CLK_SRC_TOP0 = 0x01110000
CLK_SRC_TOP1 = 0x00001000
Now calculate the clock frequency of ARMCLK:
From the introduction of the previous section "Analysis of the Exynos4412 Clock System", we know that ARMCLK has the following calculation formula:
As shown below:
The value of the register CLK_SRC_CPU printed above is:
Hexadecimal: 0x01000001
Binary: 0000 0001 0000 0000 0000 0000 0000 0001
BIT[0] controls the first MUX (i.e. MUXAPLL), and the value of this bit is 1.
BIT[16] controls the second MUX (i.e. MUXCORE), and the value of this bit is 0.
So it can be seen that the ARMCLK clock follows the following route:
So: ARMCLK = output of MUXCORE / DIVCORE / DIVCORE2
ARMCLK = MDIV x FIN / (PDIV x 2 ^ SDIV) / (CORE_RATIO + 1) / (CORE2_RATIO + 1)
= 0x64 x 24MHz / (3 x 2 ^ 1) / (0 + 1) / (0 + 1)
= 400 MHz
This experiment involves 3 small experiments:
system_clock_disable_apll: Do not use APLL, let the CPU run at 24MHz frequency, and observe whether the LED flashing becomes slower
system_clock_apll: Reset APLL to make the CPU run at 1.4GHz and observe whether the LED flashes faster.
system_clock_plls: Refer to the u-boot code provided by the manufacturer to set up all PLLs for use in subsequent chapters. The first small experiment
Goal: Do not use APLL, let the CPU run at 24MHz frequency, and observe whether the LED flashing becomes slower
1. Program Description
We modified the previous experiment based on "Tiny4412's C language implementation of flowing lights".
start.S is mostly the same, except for the addition of a function call statement
bl system_clock_init //Call the clock initialization function
As shown below:
The content of the link script system_clock.lds is exactly the same as key.lds in the previous experiment, only the name is changed; the content of Makefile is also mostly the same, only the name of the file inside is changed, the led.c file is exactly the same as in the LED experiment, and a new file system_clock.c is added, the code is as follows:
/* CMU_CPU */
#define CLK_SRC_CPU (*(volatile unsigned int *)0x10044200)
#define CLK_DIV_CPU0 (*(volatile unsigned int *)0x10044500)
#define CLK_DIV_CPU1 (*(volatile unsigned int *)0x10044504)
/* CMU_DMC */
#define CLK_SRC_DMC (*(volatile unsigned int *)0x10040200)
#define CLK_DIV_DMC0 (*(volatile unsigned int *)0x10040500)
#define CLK_DIV_DMC1 (*(volatile unsigned int *)0x10040504)
/* CMU_TOP */
#define CLK_SRC_TOP0 (*(volatile unsigned int *)0x1003C210)
#define CLK_SRC_TOP1 (*(volatile unsigned int *)0x1003C214)
#define CLK_DIV_TOP (*(volatile unsigned int *)0x1003C510)
/* CMU_LEFTBUS */
#define CLK_SRC_LEFTBUS (*(volatile unsigned int *)0x10034200)
#define CLK_DIV_LEFTBUS (*(volatile unsigned int *)0x10034500)
/* CMU_RIGHTBUS */
#define CLK_SRC_RIGHTBUS (*(volatile unsigned int *)0x10038200)
#define CLK_DIV_RIGHTBUS (*(volatile unsigned int *)0x10038500)
/* locktime */
#define APLL_LOCK (*(volatile unsigned int *)0x10044000)
#define MPLL_LOCK (*(volatile unsigned int *)0x10044008)
#define EPLL_LOCK (*(volatile unsigned int *)0x1003C010)
#define VPLL_LOCK (*(volatile unsigned int *)0x1003C020)
/* APLL */
#define APLL_CON1 (*(volatile unsigned int *)0x10044104)
#define APLL_CON0 (*(volatile unsigned int *)0x10044100)
/* MPLL */
#define MPLL_CON0 (*(volatile unsigned int *)0x10040108)
#define MPLL_CON1 (*(volatile unsigned int *)0x1004010c)
/* EPLL */
#define EPLL_CON2 (*(volatile unsigned int *)0x1003C118)
#define EPLL_CON1 (*(volatile unsigned int *)0x1003C114)
#define EPLL_CON0 (*(volatile unsigned int *)0x1003C110)
/* VPLL */
#define VPLL_CON0 (*(volatile unsigned int *)0x1003C120)
#define VPLL_CON1 (*(volatile unsigned int *)0x1003C124)
#define VPLL_CON2 (*(volatile unsigned int *)0x1003C128)
/*
* Function name:
* system_clock_init
* Function: Initialize the system clock of 4412
*/
void system_clock_init(void)
{
/* IROM or BL1 sets APLL,
* This program does not start APLL.
* Instead, use the crystal oscillator clock to experience the LED flashing becoming slower
*/
CLK_SRC_CPU = 0x0;
}
There is nothing much to say, it is very simple. The first part is the definition of some register addresses that will be used later. The main one is the system_clock_init function below. In this function, the value of the CLK_SRC_CPU register is set to 0, so that the frequency of ARMCLK will follow the following path and be set to 24MHZ:
2. Compile and burn experiments
According to the methods introduced in the previous sections, upload the program to the server for compilation and burn it to the SD card. Power on the development board and you can clearly feel that the frequency of LED flashing is greatly reduced, indicating that the clock we set is working. I won’t post a picture here (you can’t see it even if I do).
The second small experiment
Goal: Reset APLL, let the CPU run at 1.4GHz, and observe whether the LED flashes faster
1. Program Description
The file is the same as the first small experiment, except that the system_clock_init function in the system_clock.c file is modified based on it:
/*
* Function name: system_clock_init
* Function: Initialize the system clock of 4412
* Final result: APLL=1.4GHz
*/
void system_clock_init(void)
{
/*
* 1. Before setting APLL, first set the clock source to crystal oscillator
*/
CLK_SRC_CPU = 0x0;
/*
* 2. Set APLL
*/
/* 2.1 Set lock time: PDIV=3 in APLL_CON0, so APLL_LOCK = 270x3 */
APLL_LOCK = 270 * 3;
/* 2.2 Set frequency division parameters*/
/*
* CORE2_RATIO = 0;
* APLL_RATIO = 2;
* PCLK_DBG_RATIO = 1;
* ATB_RATIO = 6;
* PERIPH_RATIO = 7;
* COREM1_RATIO = 7;
* COREM0_RATIO = 3;
* CORE_RATIO = 0;
*/
CLK_DIV_CPU0 = ((0<<28) | (2<<24) | (1<<20) | (6<<16) | (7<<12) | (7<<8) | (3<<4) | 0);
/*
* CORES_RATIO = 5;
* HPM_RATIO = 0;
* COPY_RATIO = 6;
*/
CLK_DIV_CPU1 = ((5 << 8) |(0 << 4) | (6));
/* 2.3 Set control parameters and enable PLL */
/* default value*/
APLL_CON1 = 0x00803800;
/*
* Set APLL's M, P, S values, APLL output = 0xAF x 24MHz / (3 x 2 ^ 0) = 1.4GHz
* Enable APLL
*/
APLL_CON0 = (1<<31 | 0xAF<<16 | 3<<8 | 0x0);
/* 3. Set up MUX and use the output of APLL*/
CLK_SRC_CPU = 0x01000001;
}
The comments are very clear. What needs to be noted is that after power-on, IROM sets APLL, and the CPU works on the clock provided by APLL. When we want to change APLL, we must first make the CPU work on another clock source, that is, the crystal oscillator. After setting APLL, let the CPU work on the clock provided by APLL again.
2. Compile and burn experiments
According to the methods introduced in the previous sections, upload the program to the server for compilation and burn it to the SD card. When the development board is powered on, you can clearly feel that the frequency of LED flashing has greatly increased (it flashes faster than in "Tiny4412 C language to implement flowing lights", because the CPU was running at 400MHZ at that time, and now it runs at 1.4GHZ), which means that the clock we set is effective. I won't post a picture here (you can't see it even if I post a picture).
The third small experiment
Goal: Refer to the u-boot code provided by the manufacturer and set up all PLLs for use in subsequent chapters
1. Program Description
The file is the same as the first small experiment, except that the system_clock_init function in the system_clock.c file is modified based on it:
/*
Function name:
system_clock_init
Function:
Initialize the system clock of 4412
Final Results:
A=1400000000, M=800000000, E=96000000 V=350000000
ARMCLK=1500000000, DMC=400000000, ACLK200=160000000
ACLK100=100000000, ACLK160=160000000, ACLK133=133333333
*/
void system_clock_init(void)
{
/* 1. Set CMU_CPU related*/
CLK_SRC_CPU = 0x0; // Set the source of all MUXs in the CMU_CPU section
/* 2. Set CMU_DMC related*/
/*
CORE_TIMERS_RATIO = 0x0;
COPY2_RATIO = 0x0;
DMCP_RATIO = 0x1;
DMCD_RATIO = 0x1;
DMC_RATIO = 0x1;
DPHY_RATIO = 0x1;
ACP_PCLK_RATIO = 0x1;
ACP_RATIO = 0x3;
*/
CLK_DIV_DMC0 = ((0x0 << 28) | (0x0 << 24) | (0x1 << 20) | (0x1 << 16) | (0x1 << 12) | (0x1 << 8) | (0x1 << 4) | (0x3));
CLK_DIV_DMC1 = 0x07071713;
/* 3. Set CMU_TOP related*/
/*
MUX_ONENAND_SEL = 0x0;
MUX_ACLK_133_SEL = 0x0;
MUX_ACLK_160_SEL = 0x0;
MUX_ACLK_100_SEL = 0x0;
MUX_ACLK_200_SEL = 0x0;
MUX_VPLL_SEL = 0x1;
MUX_EPLL_SEL = 0x1;
*/
CLK_SRC_TOP0 = ((0x0 << 28) | (0x0 << 24) | (0x0 << 20) | (0x0 << 16) | (0x0 << 12) | (0x1 << 8) | (0x1 << 4));
CLK_SRC_TOP1 = 0x01111000;
/*
ACLK_400_MCUISP_RATIO = 0x1;
ACLK_266_GPS_RATIO = 0x2;
ONENAND_RATIO = 0x1;
ACLK_133_RATIO = 0x5;
ACLK_160_RATIO = 0x4;
ACLK_100_RATIO = 0x7;
ACLK_200_RATIO = 0x4;
*/
CLK_DIV_TOP = ((0x1 << 24) | (0x2 << 20) | (0x1 << 16) | (0x5 << 12) | (0x4 << 8) | (0x7 << 4) | (0x4));
/* 3. Set CMU_LEFTBUS related*/
CLK_SRC_LEFTBUS = 0x10;
/*
GPL_RATIO = 0x1;
GDL_RATIO = 0x3;
*/
CLK_DIV_LEFTBUS = ((0x1 << 4) | (0x3));
/* 4. Set CMU_RIGHTBUS related*/
CLK_SRC_RIGHTBUS = 0x10;
/*
GPR_RATIO = 0x1;
GDR_RATIO = 0x3;
*/
CLK_DIV_RIGHTBUS = ((0x1 << 4) | (0x3));
Previous article:TINY4412 bare metal program, key detection
Next article:tiny4412 bare metal program 1. Description
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- [Xingkong Board Python Programming Learning Main Control Board] Use of various sensor functions and network connection
- Espressif ESP32-S3-BOX-LITE lights up the RGB light
- U-boot transplantation record
- I got a Raspberry Pi Pico and turned it on
- LED chip and driver circuit application quick reference
- #Idle Market# Memory stick, CPU
- TI millimeter wave radar classification and technical solutions
- The SD card driver code is really difficult
- I have a question, what is the principle of the Wolman amplifier circuit, the role of the common-emitter amplifier and the common-base amplifier, and how do they amplify?
- Two-color illustration of the core knowledge and selection of electronic components