pll 锁相环, 倍频
串口工作核心图
//start.s AREA start_main,CODE, READONLY ENTRY IMPORT uart_test START B uart_test END //uart.c #define ULCON0 *((volatile unsigned int *)0XE2900000) #define UCON0 *((volatile unsigned int *)0XE2900004) #define UTRSTAT0 *((volatile unsigned int *)0XE2900010) #define UTXH0 *((volatile unsigned int *)0XE2900020) #define URXH0 *((volatile unsigned int *)0XE2900024) #define UBRDIV0 *((volatile unsigned int *)0XE2900028) #define UDIVSLOT0 *((volatile unsigned int *)0XE290002C) #define GPACON0 *((volatile unsigned int *)0XE0200000) void uart_init(void) { //串口管脚设置成功能态 GPACON0 = 0x22; //设置8 N 1 ULCON0 = 0X3; //设置轮询工作模式 UCON0 = 0X5; //设置波特率 UBRDIV0 = 34; UDIVSLOT0 = 0XDDDD; } char uart_getchar(void) { char ch; //如果有数据到达,状态寄存器第0位置1 //判断状态位是否为1,决定读接收缓冲寄存器,读到的值作为函数的返回值 while (!(UTRSTAT0 & 0x1)) ; ch = URXH0; return ch; } void uart_putchar(char ch) { //如果状态寄存器第1为置1,表示发送单元为空,可以发送数据 //把ch赋值到发送缓冲寄存器里,状态寄存器第1为置0, 自动发送,当发送完毕 while (!(UTRSTAT0 & 0X2)) ; UTXH0 = ch; } void uart_test(void) { char ch; uart_init(); uart_putchar('a'); uart_putchar('b'); uart_putchar('c'); //串口回显功能 while (1) { ch = uart_getchar(); uart_putchar(ch); } }
--------------------------------------------------
内存是总线设备,nandflash属于非总线设备。
裸板操作NandFlash的示例代码:
#define NFCONF (*(volatile unsigned int *)0xB0E00000) #define NFCONT (*(volatile unsigned int *)0xB0E00004) #define NFCMMD (*(volatile unsigned int *)0xB0E00008) #define NFADDR (*(volatile unsigned int *)0xB0E0000C) #define NFDATA (*(volatile unsigned int *)0xB0E00010) #define NFSTAT (*(volatile unsigned int *)0xB0E00028) #define MP0_3CON (*(volatile unsigned int *)0xE0200320) #define PAGE_SIZE 2048 void nand_init(void) { //[15:12]TACLS = 1->(1) 1/133Mhz = 7.5ns //[11:8] TWRPH0 = 1->(1+7) 7.5ns*2 = 15ns //[7:4] TWRPH1 = 1->(1+1) 7.5ms *2 = 15ns NFCONF |= 1<<2 | 1<< 8 | 1<< 4; //AdrCycle [1]1=5 address cycle NFCONF |= 1<<1; //MODE [0] NAND Flash controller operating node // 0=disable nand flash controller // *1 = enable nand flash controller NFCONT |= 1<<0; //Reg_nCE0 [1] nandflash memort nRCS[0] signal control // *0 = force nRCS[0] to low (enable chip select) // 1 = force nRCS[0] to high(disable chip select) NFCONT &= ~(1<<1); //GPIO functional mux setting // 0010 = NF_xxx MP0_3CON = 0X22222222; return ; } void nand_read_id(char id[]) { int i; //write read_id cmd 90th NFCMMD = 0X90; //write address 00h NFADDR = 0x00; for(i=0; i<5; i++) { id[i] = NFDATA; } return ; } void nand_read_page(int addr, char buf[]) { int i; char tmp; //write read_page cmd 00h NFCMMD = 0X00; //write 5 address NFADDR = (addr >> 0) & 0xFF; NFADDR = (addr >> 8) & 0x7; NFADDR = (addr >> 11) & 0xFF; NFADDR = (addr >> 19) & 0xFF; NFADDR = (addr >> 27) & 0x1; //write read_page cmd 30h NFCMMD = 0X30; //wait for R/nB -->ready while( (NFSTAT &(1<<0))==0 ) ; //read data 2048 bytes for(i=0; i<PAGE_SIZE; i++) { buf[i] = NFDATA; } for (i=0; i<64; i++) { tmp = NFDATA; } return ; } void nand_read(int nand_addr, char *sdram_addr, int size) { int pages = (size -1)/PAGE_SIZE + 1; int i; for (i=0; i<pages; i++) { nand_read_page(nand_addr + i*PAGE_SIZE, sdram_addr + i*PAGE_SIZE); } }uboot中操作NandFlash的示例代码:
//s3c2440_nand.c
#include <common.h> #if 0 #define DEBUGN printf #else #define DEBUGN(x,args ...){} #endif #include <nand.h> #include <asm/arch/s3c24x0_cpu.h> #include <asm/arch/s3c2410.h> #include <asm/io.h> #define __REGb(x) (*(volatile unsigned char *)(x)) #define __REGi(x) (*(volatile unsigned int *)(x)) #define NF_BASE 0x4e000000 #define NFCONF __REGi(NF_BASE + 0x0) #define NFCONT __REGi(NF_BASE + 0x4) #define NFCMD __REGb(NF_BASE + 0x8) #define NFADDR __REGb(NF_BASE + 0xc) #define NFDATA __REGb(NF_BASE + 0x10) #define NFMECCD0 __REGi(NF_BASE + 0x14) #define NFMECCD1 __REGi(NF_BASE + 0x18) #define NFSECCD __REGi(NF_BASE + 0x1C) #define NFSTAT __REGb(NF_BASE + 0x20) #define NFSTAT0 __REGi(NF_BASE + 0x24) #define NFSTAT1 __REGi(NF_BASE + 0x28) #define NFMECC0 __REGi(NF_BASE + 0x2C) #define NFMECC1 __REGi(NF_BASE + 0x30) #define NFSECC __REGi(NF_BASE + 0x34) #define NFSBLK __REGi(NF_BASE + 0x38) #define NFEBLK __REGi(NF_BASE + 0x3C) #define S3C2440_NFCONT_nCE (1<<1) #define S3C2440_ADDR_NALE 0x08 #define S3C2440_ADDR_NCLE 0x0c #ifdef CONFIG_NAND_SPL /* in the early stage of NAND flash booting, printf() is not available */ #define printf(fmt, args...) static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { int i; struct nand_chip *this = mtd->priv; for (i = 0; i < len; i++) buf[i] = readb(this->IO_ADDR_R); } #endif ulong IO_ADDR_W = NF_BASE; static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { struct nand_chip *chip = mtd->priv; DEBUGN("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl); if (ctrl & NAND_CTRL_CHANGE) { IO_ADDR_W = NF_BASE; if (!(ctrl & NAND_CLE)) IO_ADDR_W |= S3C2440_ADDR_NCLE; if (!(ctrl & NAND_ALE)) IO_ADDR_W |= S3C2440_ADDR_NALE; if (ctrl & NAND_NCE) NFCONT &= ~ S3C2440_NFCONT_nCE; else NFCONT |= S3C2440_NFCONT_nCE; } if (cmd != NAND_CMD_NONE) writeb(cmd, (void *)IO_ADDR_W); } static int s3c2440_dev_ready(struct mtd_info *mtd) { DEBUGN("dev_ready\n"); return(NFSTAT & 0x01); } #ifdef CONFIG_S3C2410_NAND_HWECC void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode) { struct s3c2410_nand *nand = s3c2410_get_base_nand(); debugX(1, "s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode); writel(readl(&nand->NFCONF) | S3C2410_NFCONF_INITECC, &nand->NFCONF); } static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) { struct s3c2410_nand *nand = s3c2410_get_base_nand(); ecc_code[0] = readb(&nand->NFECC); ecc_code[1] = readb(&nand->NFECC + 1); ecc_code[2] = readb(&nand->NFECC + 2); debugX(1, "s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n", mtd , ecc_code[0], ecc_code[1], ecc_code[2]); return 0; } static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { if (read_ecc[0] == calc_ecc[0] && read_ecc[1] == calc_ecc[1] && read_ecc[2] == calc_ecc[2]) return 0; printf("s3c2410_nand_correct_data: not implemented\n"); return -1; } #endif int board_nand_init(struct nand_chip *nand) { u_int32_t cfg; u_int8_t tacls, twrph0, twrph1; struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power(); DEBUGN("board_nand_init()\n"); writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON); /* initialize hardware */ twrph0 = 4; twrph1 =2; tacls = 0; cfg = ((tacls<<12)|(twrph0<<8)|(twrph1<<4)); NFCONF=cfg; cfg = ((1<<6)|(1<<4)|(0<<1)|(1<<0)); NFCONT=cfg; /* initialize nand_chip data structure */ nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010; /* read_buf and write_buf are default */ /* read_byte and write_byte are default */ /* hwcontrol always must be implemented */ nand->cmd_ctrl = s3c2440_hwcontrol; nand->dev_ready = s3c2440_dev_ready; nand->ecc.mode = NAND_ECC_SOFT; DEBUGN("end of nand_init\n"); return 0; }