📄 system.asm
字号:
/****************************************************************************
Include Section
*****************************************************************************/
#include "configurations.h"
#include "global.h"
#include "macros.h"
#include "libdsp.h"
#include "ezkitBF537_initcode.h"
/*****************************************************************************
Symbolic constants / definitions
******************************************************************************/
/*****************************************************************************
Prototypes
******************************************************************************/
.GLOBAL __clear_reg;
.GLOBAL __get_vco_hz;
.GLOBAL __get_cclk_hz;
.GLOBAL __get_sclk_hz;
.GLOBAL __get_rdiv;
.GLOBAL __full_on;
/*****************************************************************************
Functions
******************************************************************************/
.SECTION L1_code;
/****************************************************************************
Function: __clear_reg
Description: set all core register to zero
Input Parameters: none
Return Parameters: none
Registers Used: R7:0,P5:0
A1:0,ASTAT
B3:0,I3:0,M3:0,L3:0
LC1:0,LT1:0,LB1:0
Global Registers Used: none
Global Variables Used: none
C-Callable : no
*****************************************************************************/
__clear_reg:
link 0;
/* Clear General Registers (genreg): [R7:0], [P5:0], SP, FP, [A1:0] */
R0 = 0; R1 = 0; R2 = 0; R3 = 0; R4 = 0; R5 = 0; R6 = 0; R7 = 0;
P0 = 0; P1 = 0; P2 = 0; P3 = 0; P4 = 0; P5 = 0;
A0 = 0; A1 = 0; ASTAT = R7;
/* Clear DAG Registers (dagreg): [B3:0], [I3:0], [M3:0], [L3:0] */
B0 = 0; B1 = 0; B2 = 0; B3 = 0;
I0 = 0; I1 = 0; I2 = 0; I3 = 0;
M0 = 0; M1 = 0; M2 = 0; M3 = 0;
L0 = 0; L1 = 0; L2 = 0; L3 = 0;
/* FYI: System Registers (sysreg): ASTAT, SEQSTAT, SYSCFG, RETI, RETX, RETN, RETE, RETS,
LC0 and LC1, LT0 and LT1, LB0 and LB1, CYCLES, CYCLES2, and EMUDAT */
LC0 = P5; LT0 = P5; LB0 = P5;
LC1 = P5; LT1 = P5; LB1 = P5;
unlink;
rts;
__clear_reg.end:
/****************************************************************************
Name: __get_vco_hz
Description: get PLL VCO frequency in Hz
Input Parameters: none
Return Parameters: R0 = VCO
Registers Used: R7:6,P5
Global Registers Used: none
C-Callable : no
*****************************************************************************/
__get_vco_hz:
link 0;
[--SP] = ASTAT;
[--SP] = (R7:6,P5:5);
IMM32(P5,SYS_MMR_BASE);
/* get current MSEL */
R7 = w[P5 + lo(PLL_CTL)] (z);
R0 = MSEL (z);
R0 = R0 & R7;
R0 >>= 9; /* R0 = current MSEL */
/* get current VCO */
IMM32(R6,CLKIN_Hz); /* R6 = CLKIN [Hz] */
R0 *= R6; /* R0 = MSEL * CLKIN */
R6 = DF (z); /* R6 = DF bit */
R6 = R6 & R7; /* R6 = DF bit [1/0] */
R0 >>= R6; /* R0 = current VCO [Hz] */
(R7:6,P5:5) = [SP++];
ASTAT = [SP++];
unlink;
rts;
__get_vco_hz.end:
/****************************************************************************
Name: __get_cclk_hz
Description: get core clock frequency in Hz
Input Parameters: none
Return Parameters: R0 = CCLK
Registers Used: R7:6,P5
Global Registers Used: none
C-Callable : no
*****************************************************************************/
__get_cclk_hz:
link 0;
[--SP] = ASTAT;
[--SP] = (R7:6,P5:5);
IMM32(P5,SYS_MMR_BASE);
R7 = w[P5 + lo(PLL_CTL)] (z);
CC = bittst(R7,bitpos(BYPASS));
IMM32(R0,CLKIN_Hz);
if CC jump get_cclk_hz.skip;
call __get_vco_hz; /* R0 = current VCO [Hz] */
/* get current CSEL */
R7 = w[P5 + lo(PLL_DIV)] (z);
R6 = CSEL (z);
R7 = R7 & R6;
R7 >>= 4; /* R7 = current CSEL */
R0 >>= R7; /* R0 = current CCLK */
get_cclk_hz.skip:
(R7:6,P5:5) = [SP++];
ASTAT = [SP++];
unlink;
rts;
__get_cclk_hz.end:
/****************************************************************************
Name: __get_sclk_hz
Description: get system clock frequency in Hz
Input Parameters: none
Return Parameters: R0 = SCLK
Registers Used: R1,R7,P5
Global Registers Used: none
C-Callable : no
*****************************************************************************/
__get_sclk_hz:
link 0;
[--SP] = ASTAT;
[--SP] = R7;
[--SP] = R1;
[--SP] = P5;
IMM32(P5,SYS_MMR_BASE);
R7 = w[P5 + lo(PLL_CTL)] (z);
CC = bittst(R7,bitpos(BYPASS));
IMM32(R0,CLKIN_Hz);
if CC jump get_sclk_hz.skip;
call __get_vco_hz; /* R0 = current VCO [Hz] */
/* get current SSEL */
R1 = w[P5 + lo(PLL_DIV)] (z);
R7 = SSEL (z);
R1 = R1 & R7; /* R1 = current SSEL */
/* get current SCLK */
udiv32(); /* Registers passed: Dividend = R0, Divisor = R1, Quotient -> R0 */
/* R0 = current SCLK */
get_sclk_hz.skip:
P5 = [SP++];
R1 = [SP++];
R7 = [SP++];
ASTAT = [SP++];
unlink;
rts;
__get_sclk_hz.end:
/****************************************************************************
Name: __get_rdiv
Description: Calculate RDIV value for SDRAM Refresh Rate Control Register
RDIV = ( ( SCLK[MHz] * tREF[ms] ) / NRA ) - ( tRAS + tRP ) [clock cycles]
RDIV = ( ( SCLK * 10^6 * 1/s * tREF * 10^-3 s ) / NRA ) - ( tRAS + tRP ) [clock cycles]
SCLK = ( CLKIN * MSEL ) / SSEL = VCO / SSEL
VCO = get_vco_hz
SCLK = get_sclk_hz
MSEL = Extracted from PLL_CTL register
SSEL = Extracted from PLL_DIV register
tREF = Definition
NRA = Definition
tRAS = Extracted from EBIU_SDGCTL
tRP = Extracted from EBIU_SDGCTL
Input Parameters: none
Return Parameters: R0 = RDIV_VAL
Registers Used: R7:1
Global Registers Used: none
C-Callable : no
*****************************************************************************/
__get_rdiv:
link 0;
[--SP] = ASTAT;
[--SP] = (R7:1);
call __get_sclk_hz; /* R0 = current SCLK [Hz] */
R1 = NRA (z);
R7 = 1000 (z);
R1 *= R7;
udiv32();
R7 = tREF (z); /* R7 = tREF [ms] */
R0 *= R7; /* R0 = ( SCLK / NRA ) * tREF */
IMM32(R7,EBIU_SDGCTL_VAL);
/* get tRP */
R5 = TRP;
R5 = R5 & R7;
R5 >>= 11; /* R5 = tRP */
/* get tRAS */
R6 = TRAS;
R6 = R6 & R7;
R6 >>= 6; /* R6 = tRAS */
R7 = R5 + R6; /* R7 = tRAS + tRP */
R0 = R0 - R7; /* R0 = RDIV */
(R7:1) = [SP++];
ASTAT = [SP++];
unlink;
rts;
__get_rdiv.end:
/****************************************************************************
Name: __full_on
Description: bring processor to full on mode
Input Parameters: none
Return Parameters: none
Registers Used: R7:6,P5
Global Registers Used: none
C-Callable : no
*****************************************************************************/
__full_on:
link 0;
[--SP] = ASTAT;
[--SP] = (R7:6,P5:5);
IMM32(P5,SYS_MMR_BASE);
/*****************************************************************************************
Description: Dynamic Power Managment
Important Notice:
Depending on increasing/decreasing speed (core clock (CCLK) and/or system clock (SCLK)),
the order of the registers PLL_CTL, PLL_DIV (and VR_CTL) have to be adapted!
- Increase speed: 1. VR_CTL, 2. PLL_DIV, 3. PLL_CTL
- Decrease speed: 1. PLL_CTL, 2. PLL_DIV, 3. VR_CTL
If SDRAM is in use, the value for RDIV in the EBIU_SDRRC register has to be re-calculated
*****************************************************************************************/
/**************************
* PLL Lock Count Register *
**************************/
R7.L = PLL_LOCKCNT_VAL;
w[P5 + lo(PLL_LOCKCNT)] = R7;
/*****************************************************************************
Description: Configure Voltage Regulator Control Register
IMPORTANT
NOTICE: The same value should not be written twice
to the VR_CTL register
******************************************************************************/
R6 = w[P5 + lo(VR_CTL)] (z);
R7 = VR_CTL_VAL (z);
CC = R6 == R7;
if CC jump skip_vr_ctl;
cli R6; /* disable interrupts */
w[P5 + lo(VR_CTL)] = R7; /* Apply VR_CTL changes */
idle; /* drain pipeline and send core into IDLE. Required for changing voltage settings */
sti R6; /* re-enable interrupts after wakeup */
skip_vr_ctl: nop;
/*********************************
* PLL Divide Register *
* Can be configured on the fly *
* First configure divider, *
* than configure MSEL in PLL_CTL *
*********************************/
R7.L = PLL_DIV_VAL;
w[P5 + lo(PLL_DIV)] = R7;
/*****************************************************************************
Description: Configure PLL Control Register
IMPORTANT
NOTICE: The same value should not be written twice
to the PLL_CTL register
IMPORTANT
NOTICE
for BF561: Core B must be in idle state during this programming sequence
******************************************************************************/
R6 = w[P5 + lo(PLL_CTL)] (z);
R7 = PLL_CTL_VAL (z);
CC = R6 == R7;
if CC jump skip_pll_ctl;
cli R6; /* disable interrupts */
w[P5 + lo(PLL_CTL)] = R7; /* Apply PLL_CTL changes */
idle; /* drain pipeline and send core into IDLE. Required for changing voltage settings */
sti R6; /* re-enable interrupts after wakeup */
skip_pll_ctl: nop;
(R7:6,P5:5) = [SP++];
ASTAT = [SP++];
unlink;
rts;
__full_on.end:
/****************************************************************************
EOF
*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -