The main analysis of mini2440

Source: Internet
Author: User

/****************************************************************
Name:u2440mon.c
Desc:u2440mon entry Point,menu,download
History:
mar.25.2002:purnnamu:s3c2400x profile.c is ported for s3c2410x.
MAR.27.2002:PURNNAMU:DMA is enabled.
Apr.01.2002:purnnamu:isdownloadready flag is added.
Apr.10.2002:purnnamu:-Selecting menu is available in the waiting loop.
So, Isdownloadready flag gets not needed
-UART Ch.1 can selected for the console.
Aug.20.2002:purnnamu:revision number Change 0.2-R1.1
Sep.03.2002:purnnamu:to Remove the power noise in the USB signal, the unused clkout0,1 is disabled.
****************************************************************/
#define GLOBAL_CLK 1

#include//Declare some functions that perform numeric conversions, memory allocations, and other similar work
#include//String functions
#include "def.h"
#include "Option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "Mmu.h"
#include "profile.h"
#include "Memtest.h"

extern char image$ $RO $ $Limit [];
extern char image$ $RO $ $Base [];
extern char image$ $RW $ $Limit [];
extern char image$ $RW $ $Base [];
extern char image$ $ZI $ $Limit [];
extern char image$ $ZI $ $Base [];

void Isr_init (void);
void Haltundef (void);
void Haltswi (void);
void Haltpabort (void);
void Haltdabort (void);
void clearmemory (void);

void clk0_enable (int clock_sel);
void clk1_enable (int clock_sel);
void clk0_disable (void);
void clk1_disable (void);

extern void Tft_lcd_init (void);
extern void tft_lcd_test (void);
extern void Tft_lcd_init (void);
extern void tft_lcd_test (void);
extern void Test_touchpanel (void);
extern void test_adc (void); ADC Test
extern void keyscan_test (void);
extern void Rtc_display (void);
extern void Test_irda_tx (void);
extern void playmusictest (void);
extern void recordtest (void);
extern void Test_iic (void);
extern void Test_sdi (void);
extern void camera_test (void);
Volatile affects compiler compilation results, indicating that volatile variables are at any time likely to change, with volatile variables related to the operation, do not compile optimization.
Volatile U32 downloadaddress;
void (*restart), a pointer is defined, the pointer is named restart, the pointer points to a function, and the return type of the function is void
(Void (*) (void)) 0x0, which casts 0x0 to the type that is to the left of the equals sign.
void (*restart) (void) = (void (*) (void)) 0x0;

Volatile U8 *DOWNPT;
Volatile U32 downloadfilesize;
Volatile U16 CheckSum;
Volatile U32 err=0;
Volatile U32 Totaldmacount;

Volatile S32 isusbdsetconfiguration;

int download_run=0;
U32 tempdownloadaddress;
int menuused=0;

U32 *pmagicnum= (U32 *) image$ $RW $ $Limit;
int consolenum;
/* Before the global variable, plus the keyword static, the global variable is defined as a global static variable.
1) in-memory location: static storage (static storage is present during the entire program run)
2) Initialize: Uninitialized global static variable is automatically initialized by program to 0
3) Scope: Global static variables are not visible outside the declaration of his file. Exactly where you start from the definition to the end of the file
*/
Static U32 Cpu_freq;
Static U32 UPLL;
/* Add the keyword static before the return type of the function, and the function is defined as a static function.
The definition and declaration of a function is extern by default, but the static function is only visible in the file that declares it and cannot be used by other files.
*/
static void Cal_cpu_bus_clk (void)
{
U32 Val;
U8 m, p, s;
val = Rmpllcon;
m = (val>>12) &0xff;//m=92=mdiv
p = (val>>4) &0x3f; P=1=pdiv
s = val&3; S=1=sdiv
/* Follow the manual above for calculation, fout=2*m*fin/(p*2s), where Fin=12mhz. But M, p, and s are not the same as above. M=mdiv+8,p=pdiv+2,s=sdiv in formula
(1<
FIN, FCLK defined in option.h, fin=12000000, calculated Fclk=400mhz
*/
&LT;/S), move the 1 left S bit. The logical left shift is the equivalent of multiplying by 2 n times. And the logical right shift is equivalent to dividing by 2 of the n-th square
(m+8) *fin*2 do not exceed the 32-digit number!
FCLK = ((m+8) * (fin/100)/((p+2) * (1<
val = rclkdivn;
m = (val>>1) &3; M=2=hdivn,hclk=fclk/4
p = val&1; P=1=pdivn
val = rcamdivn; Since the CAMDIVN register was not previously set, it is the default value s=0x0, its last two bits 00, representing the camdivn[9:8 before the shift]
s = val>>8;
Switch (m) {
Case 0:
HCLK = FCLK; When HDIV[2:1]=00,HCLK=FCLK/1
Break
Case 1:
HCLK = fclk>>1; When HDIV[2:1]=01,HCLK=FCLK/2
Break
Case 2:
if (s&2)
HCLK = fclk>>3; When hdiv[2:1]=10,camdivn[9]=1, it means HCLK=FCLK/8
Else
HCLK = fclk>>2; When hdiv[2:1]=10,camdivn[9]=0, it means HCLK=FCLK/4
Break
Case 3:
if (s&1)
HCLK = FCLK/6; When hdiv[2:1]=11,camdivn[8]=1, it means HCLK=FCLK/6
Else
HCLK = FCLK/3; When hdiv[2:1]=11,camdivn[8]=0, it means HCLK=FCLK/3
Break
}
if (p)
PCLK = hclk>>1; When PDIVN=1,PCLK=HCLK/2
Else
PCLK = HCLK; When PDIVN=0,PCLK=HCLK/1
if (s&0x10)//camdivn[12]=0,cpu frequency equals HCLK frequency
Cpu_freq = HCLK;
Else
Cpu_freq = FCLK; Camdivn[12]=1, indicating CPU frequency equals FCLK frequency
val = Rupllcon; Upllcon is not set in the main function, but is set in 2440init
m = (val>>12) &0xff; M=56=mdiv
p = (val>>4) &0x3f; P=2=pdiv
s = Val&3;//s=2=sdiv
UPLL = ((m+8) *fin)/((p+2) * (1&LT;//UPLL calculation method, as with MPLL, calculated, Upll=48mhz
UCLK = (rclkdivn&8)? (upll>>1): UPLL; According to the value of Clkval in 2440init, clkdivn[3]=divn_upll=0,rclkdivn&8=0, so Uclk=upll=48mhz
}</s)) (></s)) *100;

void Temp_function () {uart_printf ("\nplease input 1-16 to select Test!!! \ n "); }

struct {
void (*fun) (void); Declaring a struct
Char *tip; Declaring a function pointer
}cmdtip[] = {//struct body initialization
{temp_function, "Please input 1-16 to select Test"},
{buzzer_pwm_test, "Test PWM"},
{rtc_display, "RTC Time Display"},
{TEST_ADC, "Test ADC"},
{keyscan_test, "Test Interrupt and Key Scan"},
{test_touchpanel, "Test Touchpanel"},
{tft_lcd_test, "Test TFT-LCD or vga1024x768 module"},
{TEST_IIC, "Test Iic EEPROM, if use QQ2440, remove the LCD"},
{playmusictest, "UDA1341 Play Music"},
{TEST_SDI, "Test SD Card"},
{camera_test, "Test CMOS Camera"},
{0, 0}
};

void Main (void)
{
Char *mode;
int i;
U8 key;
U32 mpll_val = 0;
U32 DIVN_UPLL = 0;
#if如果给定条件为真, the following code is compiled until #else, #elif或 #endif are present, otherwise it is not compiled. ADS10 defined in Option.h, ads10=1, this paragraph has no effect
#if ADS10
__rt_lib_init (); For ADS 1.0
#endif
Port initialization, setting gpa/b/c/d/e/f/g/h/j the appropriate pin, EXTINT0/1/2/3
Port_init ();
Set Interrupt service program, initialize. Set all interrupts to IRQ mode, masking all interrupt requests
Isr_init ();
i = 2; Don ' t use 100m!
Boot_params.cpu_clk.val = 3;
switch (i) {
Case 0://200
Key = 12;
Mpll_val = (92<<12) | (4<<4) | (1);
Break
Case 1://300
key = 13;
Mpll_val = (67<<12) | (1<<4) | (1);
Break
Case 2://400
Set the value of the clock divider ratio, FCLK:HCLK:PCLK
key = 14;
Set the value of FCLK, mdiv=92,pdiv=1,sdiv=1
Mpll_val = (92<<12) | (1<<4) | (1);
Break
Case 3://440!!!
key = 14;
Mpll_val = (102<<12) | (1<<4) | (1);
Break
Default
key = 14;
Mpll_val = (92<<12) | (1<<4) | (1);
Break
}
Init fclk=400m, so change MPLL first
Changempllvalue ((mpll_val>>12) &0xff, (mpll_val>>4) &0x3f, mpll_val&3);
Changeclockdivider (key, 12);
CAL_CPU_BUS_CLK ();
Serial port settings: Serial port selection, serial baud rate setting;
Consolenum = 0; Uart 1 Select for Debug.
Uart_init (0,115200);
Uart_select (Consolenum);
Beep (2000, 100);
Uart_sendbyte (' \ n ');
uart_printf ("<***********************************************>\n");
uart_printf ("SBC2440 Test program ver1.0\n");
uart_printf ("www.arm9.net\n");
uart_printf ("Build time is:%s%s\n", __date__, __time__);
uart_printf ("image$ $RO $ $Base = 0x%x\n", image$ $RO $ $Base);
uart_printf ("image$ $RO $ $Limit = 0x%x\n", image$ $RO $ $Limit);
uart_printf ("image$ $RW $ $Base = 0x%x\n", image$ $RW $ $Base);
uart_printf ("image$ $RW $ $Limit = 0x%x\n", image$ $RW $ $Limit);
uart_printf ("image$ $ZI $ $Base = 0x%x\n", image$ $ZI $ $Base);
uart_printf ("image$ $ZI $ $Limit = 0x%x\n", image$ $ZI $ $Limit);
uart_printf ("<***********************************************>\n");
Different kinds of control register settings, here is the main choice of USB port
rmisccr=rmisccr&~ (1<<3); Select USB device instead of USB host
rmisccr=rmisccr&~ (1&LT;&LT;13); Set Port1 Valid

//
USBD should is initialized first of all.
//
isusbdsetconfiguration=0;
RD_DM9000_ID (); //
Rgpbcon &= ~ (3<<20); Cf_card Power
Rgpbcon |= 1<<20;
Rgpbdat |= 1<<10;
rDSC0 = 0x155;
rDSC1 = 0x15555555;
Setting the output pin drive current
rDSC0 = 0X2AA;
rDSC1 = 0X2AAAAAAA;
Enable NAND, USBD, PWM TImer, uart0,1 and GPIO clock,
The others must is enabled in OS!!!
Set the clock control register to select the clock source for each external interface
Rclkcon = 0xfffff0;

Mmu_enableicache ();
Mmu_init (); Memory storage Management. The bare-Ben is temporarily unused.
uart_printf ("NOR Flash ID is 0x%08x\n", Getflashid ());

Pisr_swi= (_ISR_STARTADDRESS+0XF0); For PSOS
Gpb5=nled1,gpb6=nled2,gpb7=nled3,gpb8=nled4
LED2, 3 bright
Led_display (0x66);

#if USBDMA
Mode= "DMA";
#else
Mode= "Int";
#endif

CLKOUT0/1 Select.
uart_printf ("Clkout0:mpll in, Clkout1:rtc clock.\n");
Clk0_enable (0); 0:mpllin, 1:UPLL, 2:FCLK, 3:HCLK, 4:PCLK, 5:dclk0
Clk1_enable (2); 0:mpllout, 1:UPLL, 2:RTC, 3:HCLK, 4:PCLK, 5:DCLK1
Clk0_disable ();
Clk1_disable ();
Read back the value of the PLL control register into the variable;
Mpll_val = Rmpllcon;
Tft_lcd_init ();
Tft_lcd_init ();
Download_run=1; The default menu is the Download & Run mode.

while (1)
{
U8 idx;
uart_printf ("\nplease select function: \ n");
for (i=0; cmdtip[i].fun!=0; i++)
Uart_printf ("%d:%s\n", I, Cmdtip[i].tip);
IDX = UART_GETINTNUM_GJ (); function function Converts the string received by the serial port to the int data from the form (the binary) to return
if (idx
</i)
{
(*cmdtip[idx].fun)  (); Call the appropriate function function
Delay (20);
Uart_init (0,115200);
}
}

}

void Isr_init (void)
{
pisr_undef= (unsigned) haltundef;
PISR_SWI = (unsigned) haltswi;
pisr_pabort= (unsigned) haltpabort;
pisr_dabort= (unsigned) haltdabort;
rintmod=0x0; ALL=IRQ mode
Rintmsk=bit_allmsk; All interrupt are masked.

pisr_urxd0= (unsigned) uart0_rxint;
rintmsk=~ (BIT_URXD0); Enable UART0 RX Default VALUE=0XFFFFFFFF

#if 1
PISR_USBD = (unsigned) ISRUSBD;
Pisr_dma2 = (unsigned) IsrDma2;
#else
PISR_IRQ = (unsigned) ISRUSBD;
Why doesn ' t it to receive the big file if use this. (???)
It always stops when 327680 bytes is received.
#endif
Clearpending (BIT_DMA2);
Clearpending (BIT_USBD);
rintmsk&=~ (BIT_USBD);
PISR_FIQ,PISR_IRQ must be initialized
}

void Haltundef (void)
{
uart_printf ("Undefined instruction exception!!! \ n ");
while (1);
}

void Haltswi (void)
{
uart_printf ("SWI exception!!! \ n ");
while (1);
}

void Haltpabort (void)
{
uart_printf ("Pabort exception!!! \ n ");
while (1);
}

void Haltdabort (void)
{
uart_printf ("Dabort exception!!! \ n ");
while (1);
}

void Clearmemory (void)
{
int i;
U32 data;
int memerror=0;
U32 *pt; Set a pointer variable pt, which stores the address of each storage unit in memory, because the system constructs a 32-bit data bus, so the type of PT is unsigned unsigned int.
uart_printf ("Clear Memory (%XH-%XH): WR", _ram_startaddress,heapend); Output log, information for the storage test start, first men write operation, the output operation range is address 0x30000000h to 0x33ff0000h

pt= (U32 *) _ram_startaddress; First, the start address is assigned to the pointer variable pt, and the pointer points to the start address of the test 0x30000000
while ((U32) pt < heapend)//define a loop statement, the condition of the loop end is pt>0x33ff0000
{
*pt= (U32) 0x0; Clear Memory Start
pt++; PT points to the next storage cell
}
if (memerror==0) uart_printf ("\b\bo.k.\n"); The condition comparison see whether the flag variable Memerror is false, if false that no error occurs, the detection ends, the output "o.k.", the program ends.
}

void clk0_enable (int clock_sel)
{//0:mpllin, 1:UPLL, 2:FCLK, 3:HCLK, 4:PCLK, 5:dclk0
RMISCCR = rmisccr&~ (7<<4) | (CLOCK_SEL<<4);
Rgphcon = rgphcon&~ (3<<18) | (2<<18);
}
void clk1_enable (int clock_sel)
{//0:mpllout, 1:UPLL, 2:RTC, 3:HCLK, 4:PCLK, 5:DCLK1
RMISCCR = rmisccr&~ (7<<8) | (CLOCK_SEL<<8);
Rgphcon = rgphcon&~ (3<<20) | (2<<20);
}
void clk0_disable (void)
{
Rgphcon = rgphcon&~ (3<<18); GPH9 Input
}
void clk1_disable (void)
{
Rgphcon = rgphcon&~ (3<<20); GPH10 Input
}

After we have set up 2440 of the hardware platform, when we debug the hardware, we usually need to test the system's clock test pin to determine whether the system meets the design requirements. The 2440 provides the CLKOUT0 and CLKOUT1 for the test clock. You can select CLKOUT0 and CLKOUT1 clock sources by setting the CLKSEL0 and CLKSEL1 bits of the MISCCR register. Its clock source has 000=MPLL output, 001 is UPLL output, 010 is RTC output, 011 is hclk,100 for pclk,101 for dclk1/0,11x.

Reprinted from Http://blog.chinaunix.net/uid-26435987-id-3137467.html

The main analysis of mini2440

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.