mini2440 nandflash简单读写调试成功 代码记录
发布时间:2020-12-15 18:11:14 所属栏目:百科 来源:网络整理
导读:又裸奔了两天,把mini2440上面的nandflash(型号是K9F1G08U0C 128M*8bit)的简单的页读写和擦除操作调通了,代码先记录下来,复杂的nandflash操作以后有时间再说,现在能够实现代码的搬移已经够了。 head.s @this is a test program of nandflash,the properti
又裸奔了两天,把mini2440上面的nandflash(型号是K9F1G08U0C 128M*8bit)的简单的页读写和擦除操作调通了,代码先记录下来,复杂的nandflash操作以后有时间再说,现在能够实现代码的搬移已经够了。 head.s @this is a test program of nandflash,the properties of com0 is the same as usual (115200,8,1,n,n) .text .global _start _start: b Reset b . @undefined instruction b . @swi b . @pregetch instruction b . @data abort b . @Reserved b HandleIRQ @irq b . @fiq Reset: ldr sp,=4096 @set the stack pointer of sys mode to 4096 bl disable_watchdog bl init_led bl init_sdram bl copy_sdram ldr pc,=on_sdram on_sdram: msr cpsr_c,#0xd2 @set cpu to irq mode ldr sp,=0x31000000 @set the stack pointer of irq mode to sdram msr cpsr_c,#0xdf @reset cpu to sys mode ldr sp,=0x32000000 bl init_clock mov r0,#1 mov r1,#10 bl blink bl init_timer0 mov r0,#2 mov r1,#10 bl blink bl init_com0 mov r0,#3 mov r1,#10 bl blink bl init_nandflash bl init_irq msr cpsr_c,#0x5f @enable irq bl main b . .ltorg .ltorg .ltorg HandleIRQ: sub lr,lr,#4 stmdb sp!,{r0-r12,lr} ldr lr,=next ldr pc,=interrupt_func next: ldmia sp!,pc}^ @return to main .ltorg .ltorg
init.c #define GPBCON (*((volatile unsigned long*)(0x56000010))) #define GPBDAT (*((volatile unsigned long*)(0x56000014))) #define WTCON (*((volatile unsigned long*)(0x53000000))) #define LOCKTIME (*((volatile unsigned long*)(0x4C000000))) #define CLKDIVN (*((volatile unsigned long*)(0x4C000014))) #define MPLLCON (*((volatile unsigned long*)(0x4C000004))) #define TCFG0 (*((volatile unsigned long*)(0x51000000))) #define TCFG1 (*((volatile unsigned long*)(0x51000004))) #define TCNTB0 (*((volatile unsigned long*)(0x5100000C))) #define TCON (*((volatile unsigned long*)(0x51000008))) #define INTMSK (*((volatile unsigned long*)(0X4A000008))) #define INTSUBMASK (*((volatile unsigned long*)(0X4A00001C))) #define GPHCON (*((volatile unsigned long*)(0x56000070))) #define GPHUP (*((volatile unsigned long*)(0x56000078))) //control register of com0 #define ULCON0 (*((volatile unsigned long*)(0x50000000))) #define UCON0 (*((volatile unsigned long*)(0x50000004))) #define UFCON0 (*((volatile unsigned long*)(0x50000008))) #define UMCON0 (*((volatile unsigned long*)(0x5000000C))) #define UBRDIV0 (*((volatile unsigned long*)(0x50000028))) //initilize GPB to output mode void init_led() { GPBCON &= (~(0xff<<10)); GPBCON |= (0X55<<10); } void delay(int times) { int i,j; for(i=0; i<times; i++) { for(j=0; j<1000; j++); } } //blink function is used to debug void blink(int number,int delay_num) { GPBDAT |= (0X0F<<5); GPBDAT &= (~(number<<5)); delay(delay_num); GPBDAT |= (0X0F<<5); delay(delay_num); } void disable_watchdog() { WTCON = 0; } void init_clock() { LOCKTIME = 0xffffffff; CLKDIVN = 0X03; //fclk:hclk:pclk=1:2:4 __asm__ ( "mrc p15,r1,c1,c0,0n" "orr r1,#0xc0000000n" "mcr p15,0n" ); MPLLCON = (92<<12)|(1<<4)|(2<<0); //fclk=200M,hclk=100M,pclk=50M } void init_sdram() { volatile unsigned long *p = (volatile unsigned long *)(0x48000000); p[0] = 0x22011110; //BWSCON p[1] = 0x00000700; //BANKCON0 p[2] = 0x00000700; //BANKCON1 p[3] = 0x00000700; //BANKCON2 p[4] = 0x00000700; //BANKCON3 p[5] = 0x00000700; //BANKCON4 p[6] = 0x00000700; //BANKCON5 p[7] = 0x00018005; //BANKCON6 p[8] = 0x00018005; //BANKCON7 p[9] = 0x008C04F4; //REFRESH value is different than before,because the clock is different p[10] = 0x000000B1; //BANKSIZE p[11] = 0x00000030; //MRSRB6 p[12] = 0x00000030; //MRSRB7 } void copy_sdram() { unsigned long* src = (unsigned long *)(0); unsigned long* des = (unsigned long *)(0x30000000); int i; for(i=0; i<1024; i++) { des[i] = src[i]; } } void init_timer0() { TCFG0 = 99; //set prescaler value to 100 TCFG1 = 0x03; //set MUX to 16 TCNTB0 = 15625; TCON = (1<<1); TCON = 0x09; //start timer0 } void init_irq() { //enable interrupt of rxd0 txd0 INTSUBMASK &= (~(0b11)); //enable interrupt of uart0 INTMSK &= (~(1<<28)); } void init_com0() { //set gph[2:3] used as txd and rxd for com0 GPHCON &= (~(0xff<<4)); GPHCON |= (0x0a<<4); //disable pull up functon for gph[2:3] GPHUP = 0x0c; //set properties of com0 ULCON0 = 0b00000011; //enable the rxd and txd,and interrupt will happen when con0 received data or the send buffer is empty in non-fifo mode UCON0 = 0b00000101; //disable fifo UFCON0 = 0x00; //disable fifo UMCON0 = 0x00; //set baud-rate to 115200 UBRDIV0 = (int)(50000000/(115200*16)) -1; }
com0.c #define UTRSTAT0 (*((volatile unsigned long*)(0x50000010))) #define UTXH0 (*((volatile unsigned long*)(0x50000020))) #define URXH0 (*((volatile unsigned long*)(0x50000024))) #define SUBSRCPND (*((volatile unsigned long*)(0X4A000018))) #define SRCPND (*((volatile unsigned long*)(0X4A000000))) #define INTPND (*((volatile unsigned long*)(0X4A000010))) extern void blink(int,int); void put_char(char ch) { while (!(UTRSTAT0 & (1<<2))); UTXH0 = ch; } unsigned char get_char() { while (!(UTRSTAT0 & (1<<0))); return URXH0; } void put_string(char *string) { int i = 0; while(string[i] != ' ') put_char(string[i++]); } void com0_read(char *ch) { *ch = URXH0; } void com0_write(char ch) { UTXH0 = ch; } //the function to serve the uart0 interrupt void interrupt_func() { char ch; //rxd sub interrupt if(SUBSRCPND & (1<<0)) { blink(15,1); com0_read(&ch); com0_write(ch); } else if(SUBSRCPND & (1<<1)) //txd interrupt { blink(10,1); } //clear the interrupt of uart0 SUBSRCPND = SUBSRCPND; SRCPND |= (1<<28); INTPND = INTPND; }
nandflash.c #define NFCONF (*((volatile unsigned long*)(0x4E000000))) #define NFCONT (*((volatile unsigned long*)(0x4E000004))) #define NFCMMD (*((volatile unsigned char*)(0x4E000008))) #define NFADDR (*((volatile unsigned char*)(0x4E00000C))) #define NFDATA (*((volatile unsigned char*)(0x4E000010))) #define NFSTAT (*((volatile unsigned long*)(0x4E000020))) #define GPACON (*((volatile unsigned char*)(0x56000000))) #define TACLS 1 #define TWPRH0 1 #define TWPRH1 1 //command #define READ1 0x00 #define READ2 0X30 #define RESET 0xff #define RANDOM_READ1 0x05 #define RANDOM_READ2 0xe0 #define WRITE1 0x80 #define WRITE2 0x10 #define RADOM_WRITE 0X85 #define ERASE1 0X60 #define ERASE2 0xd0 #define STATUS 0X70 void nandflash_reset(); void init_nandflash(); void nandflash_select_chip(); void nandflash_deselect_chip(); void nandflash_wait_ready(); extern void put_string(char *); extern void delay(int); //initilize the nandflash void init_nandflash() { //make gpa[17:22] used for nandflash controler GPACON |= (0x3f<<17); NFCONF = (TACLS<<12)|(TWPRH0<<8)|(TWPRH1<<4); NFCONT = (1<<4)|(1<<1)|(1<<0); put_string("init nandflash over!rn"); nandflash_reset(); } //reset the nandflash void nandflash_reset() { nandflash_select_chip(); NFCMMD = RESET; nandflash_wait_ready(); nandflash_deselect_chip(); } void nandflash_select_chip() { NFCONT &= (~(1<<1)); delay(3); } void nandflash_deselect_chip() { NFCONT |= (1<<1); delay(3); } void nandflash_wait_ready() { while(1) { if( (NFSTAT&(1<<0)) ) break; delay(1); } } void nandflash_read_page(unsigned int page_num,unsigned int length,unsigned char *buffer) { int i; nandflash_select_chip(); NFCMMD = READ1; NFADDR = 0x00; NFADDR = 0x00; NFADDR = (unsigned char)(page_num&0xff); NFADDR = (unsigned char)((page_num>>8)&0xff); NFCMMD = READ2; nandflash_wait_ready(); for(i=0; i<length;i++) { buffer[i] = NFDATA; } nandflash_deselect_chip(); } unsigned char nandflash_write_page(unsigned int page_num,unsigned char *buffer) { int i; unsigned char status; nandflash_select_chip(); NFCMMD = WRITE1; delay(3); NFADDR = 0x00; NFADDR = 0x00; NFADDR = (unsigned char)(page_num&0xff); NFADDR = (unsigned char)((page_num>>8)&0xff); delay(3); for(i=0; i<length;i++) { NFDATA = buffer[i]; } delay(3); NFCMMD = WRITE2; delay(30); nandflash_wait_ready(); delay(20); NFCMMD = STATUS; delay(3); status = NFDATA; nandflash_deselect_chip(); if(status & 0x01) { put_string("write error!rn"); return 0; } else { put_string("write compelete!rn"); return 1; } } unsigned char nandflash_erase_block(unsigned int block_num) { unsigned char status; nandflash_select_chip(); NFCMMD = ERASE1; NFADDR = ((block_num<<6)&0b11000000); NFADDR = ((block_num>>2)&0xff); NFCMMD = ERASE2; delay(30); nandflash_wait_ready(); delay(20); NFCMMD = STATUS; delay(3); status = NFDATA; nandflash_deselect_chip(); if(status & 0x01) { put_string("erase error!rn"); return 0; } else { put_string("erase compelete!rn"); return 1; } nandflash_deselect_chip(); }
? extern void put_char(char); extern unsigned char get_char(); extern void put_string(char *); extern void blink(int,int); extern void put_string(char*); extern void delay(int); extern void nandflash_read_page(unsigned int page_num,unsigned char *buffer); extern unsigned char nandflash_erase_block(unsigned int block_num); extern unsigned char nandflash_write_page(unsigned int page_num,unsigned char *buffer); void change_num_string(unsigned char num,char *buffer) { unsigned char num1,num0; num1 = num%16; num0 = num/16; if(num1 <= 9) buffer[1] = num1+'0'; else buffer[1] = num1-10+'A'; if(num0 <= 9) buffer[0] = num0+'0'; else buffer[0] = num0-10+'A'; buffer[2] = ' '; } int main(void) { int i; unsigned char read_buffer[20]; unsigned char write_buffer[20]; char num[3]; for(i=0; i<20; i++) { write_buffer[i] = i; } if(!nandflash_erase_block(1)) { return -1; } if(!nandflash_write_page(64,20,write_buffer)) { return -1; } nandflash_read_page(64,read_buffer); for(i=0; i<20; i++) { change_num_string(read_buffer[i],num); put_string("0x"); put_string(num); put_string("rn"); } while(1); return 0; } ? 运行结果: 总结: ??????? 以后调裸机程序一定要好好看datasheet里面的时序图然后再写程序,要不然效率极低,调试太蛋疼。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |