norflash的读,写,擦除操作。

norflash的读,写,擦除操作,不能进入CFI模式,不然会有问题。

先说读吧,

先写出工具代码吧。因为地址是word是16位的,所以用unsigned int。

#include "my_printf.h"
#include "string_utils.h"


#define BASE 0

/*读命令*/
unsigned int read_nor(unsigned int base , unsigned int offset )
{
    volatile unsigned short *p =(  volatile unsigned short *)(base + (offset << 1));  //offset<< 1是因为,这个offset是基于norflash的角度看的,nor_addr0对于cpu_addr1;
     
    return *p;
}
unsigned int do_read_nor(unsigned int offset )
{
    return read_nor(BASE,offset);
}

void write_nor(unsigned int base , unsigned int offset , unsigned int data)
{

    volatile unsigned short *p =(  volatile unsigned short *)(base + (offset << 1));
    *p = data;
}
void do_write_nor(unsigned int offset , unsigned int data)
{
    write_nor(BASE,offset,data);
}

/*****************************************************************读操作**********************************************************/

void read_norflash()
{
   int i,j;
   unsigned char string[16],c;
   unsigned int addr;
   volatile unsigned char *p ;
   printf("please input addr to read");
   addr = get_uint();
  
   p = (volatile unsigned char *)addr;
   for(i = 0 ;i < 4;i++ )
   {
        for(j = 0 ;j < 16 ;j++ )
 {
     c = *p++;;
     string[j] = c;
     printf("%02x ",c);
 }
 puts("   ;");
 for(j = 0 ;j < 16 ;j++ )
 {
     /*判断是否是可见字符*/
     if(string[j] < 0x20||string[j] > 0x7e)
     {
         putchar('.');
     }
     else
     putchar(string[j]);
    
 }
 puts("\n\r");  //每16个数据换行
  
   }
  

}

/**************************************************************写操作**********************************************************************/

void write_norflash()
{
    unsigned int addr,data;
    int i,j;
    unsigned char string[100];
      printf("please input addr\n\r");
      addr = get_uint();
     
      printf("please input data\n\r");
      gets(string);
      i=0,j=1;
      while(string[i]&&string[j])
      {
         data = string[i] + (string[j] << 8);
           do_write_nor(0x555,0xaa);//开启写模式
    do_write_nor(0x2aa,0x55);
    do_write_nor(0x555,0xa0);
           do_write_nor(addr>>1,data);
    wait_nor(addr);
    addr+=2;
           i+=2,j+=2;
      }
      data = string[i];
      do_write_nor(0x555,0xaa);//开启写模式
      do_write_nor(0x2aa,0x55);
      do_write_nor(0x555,0xa0);
      do_write_nor(addr>>1,data);          ///这里因为我们原本就是基于nor的角度,所以写nor原本就好了,>>与<<抵消;
      printf("writing!.....\n\r");
      /*还要写等待一下下*/
      wait_nor(addr);
}
/***************************************************擦除操作**********************************************************/

void erase_norflash()
{
     unsigned int addr ;
     printf("input the addr to erase \n\r");
     addr = get_uint();
     do_write_nor(0x555,0xaa);//解锁
     do_write_nor(0x2aa,0x55);
     do_write_nor(0x555,0x80);
     do_write_nor(0x555,0xaa);
     do_write_nor(0x2aa,0x55);
    
     do_write_nor(addr>>1,0x30);  //擦除
     /*等待*/
    
     wait_nor(addr);
     printf("erase!.....\n\r");
}
/*****************************************************等待地址是否操作完成***************************************************/

void wait_nor(unsigned int addr)
{
    unsigned int val , p;
   
    val = do_read_nor(addr >>1);
    p   = do_read_nor(addr >>1);

    while((val&(1 <<6))!=(p&(1 <<6)))   /
    {
        p = val;
 val = do_read_nor(addr >>1);
    }   
}


/***********************************************************菜单***************************************************************/

void nor_test()
{
    char c;
   
   
    while(1)
    {
        printf("input the [r] is read  nor \n\r");
 printf("input the [w] is write nor \n\r");
 printf("input the [c] is check nor \n\r");
 printf("input the [e] is erase nor \n\r");
 printf("input the [q] is quit  nor \n\r");
 c = getchar();
 printf("%c\n\r",c);
 switch(c)
 {
   case 'r':
   case 'R':
   read_norflash();
   break;
   case 'w':
   case 'W':
   write_norflash();
   break;
   case 'E':
   case 'e':
   erase_norflash();
   break;
   case 'c':
   case 'C':
   nor_check();
   break;
   case 'Q':
   case 'q':
  
   default :break;
 }
 
   
    }
  
}

最重要的一点就是Makefile,如果你这样写了的话,只能读,还是对nor写不了和擦除不了,因为他的指令烧写错误了,我们没有写错,是编译器对字节没有处理好,导致最终的指令不对,所以也就解锁不了。

all: start.o led.o uart.o init.o main.o exception.o interrupt.o timer.o norflash_test.o my_printf.o string_utils.o lib1funcs.o
 #arm-linux-ld -Ttext 0 -Tdata 0x30000000  start.o led.o uart.o init.o main.o -o sdram.elf
 arm-linux-ld -T sdram.lds $^ -o sdram.elf
 arm-linux-objcopy -O binary -S sdram.elf sdram.bin
 arm-linux-objdump -D sdram.elf > sdram.dis
clean:
 rm *.bin *.o *.elf *.dis
 
%.o : %.c
 arm-linux-gcc -march=armv4 -c -o $@ $<                      #这里要加个 -march=armv4

%.o : %.S
 arm-linux-gcc -march=armv4 -c -o $@ $<                      #这里要加个 -march=armv4

看我们这个写工具函数。

使用了strb 一个字节一个字节的写,我们是16位的,我们想要的是一次性先16位,用str或ldr.

当我们加上-march=armv4之后。

 

看他通过ldr,所以这样就可以一下传16位。这样就指令不会出错。

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值