chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Linux驅(qū)動(dòng)開發(fā)-編寫W25Q64(Flash)驅(qū)動(dòng)

DS小龍哥-嵌入式技術(shù) ? 2022-09-17 15:09 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

【摘要】 本篇文章就介紹如何在Linux系統(tǒng)下編寫W25Q64芯片的驅(qū)動(dòng),完成數(shù)據(jù)存儲(chǔ),W25Q64支持標(biāo)準(zhǔn)SPI總線,當(dāng)前驅(qū)動(dòng)程序底層的代碼寫了兩種方式,一種是采用內(nèi)核提供的SPI子系統(tǒng)框架,一種直接采用軟件模擬SPI時(shí)序的方式驅(qū)動(dòng),具體代碼在第3章貼出來了。

1. W25QXX介紹

W25Q64是一顆SPI接口的Flash存儲(chǔ)芯片,是華邦W25QXX系列里的一個(gè)具體型號(hào),這個(gè)系列里包含了W25Q16,W25Q32,W25Q64,W5Q128等等。編程代碼邏輯都差不多,主要是容量的區(qū)別。

本篇文章就介紹如何在Linux系統(tǒng)下編寫W25Q64芯片的驅(qū)動(dòng),完成數(shù)據(jù)存儲(chǔ),W25Q64支持標(biāo)準(zhǔn)SPI總線,當(dāng)前驅(qū)動(dòng)程序底層的代碼寫了兩種方式,一種是采用內(nèi)核提供的SPI子系統(tǒng)框架,一種直接采用軟件模擬SPI時(shí)序的方式驅(qū)動(dòng),具體代碼在第3章貼出來了。

下面是來至W25Qxx中文手冊(cè)的介紹

W25Q64 (64M-bit), W25Q16(16M-bit)和 W25Q32(32M-bit)是為系統(tǒng)提供一個(gè)最小的空間、引腳和功耗的存儲(chǔ)器解決方案的串行 Flash 存儲(chǔ)器。 25Q 系列比普通的串行 Flash 存儲(chǔ)器更靈活,性能更優(yōu)越?;陔p倍/四倍的 SPI,它們能夠可以立即完成提供數(shù)據(jù)給 RAM, 包括存儲(chǔ)聲音、文本和數(shù)據(jù)。芯片支持的工作電壓 2.7V 到 3.6V,正常工作時(shí)電流小于 5mA,掉電時(shí)低于 1uA。所有芯片提供標(biāo)準(zhǔn)的封裝。

W25Q64/16/32 由每頁 256 字節(jié)組成。 每頁的 256 字節(jié)用一次頁編程指令即可完成。 每次可以擦除 16 頁(1 個(gè)扇區(qū))、 128 頁(32KB 塊)、 256 頁(64KB 塊)和全片擦除。W25Q64 的內(nèi)存空間結(jié)構(gòu): 一頁 256 字節(jié), 4K(4096 字節(jié))為一個(gè)扇區(qū), 16 個(gè)扇區(qū)為 1 塊, 容量為 8M 字節(jié),共有 128 個(gè)塊,2048 個(gè)扇區(qū)。W25Q64/16/32 支持標(biāo)準(zhǔn)串行外圍接口(SPI),和高速的雙倍/四倍輸出,雙倍/四倍用的引腳:串行時(shí)鐘、片選端、串行數(shù)據(jù) I/O0(DI)、 I/O1(DO)、 I/O2(WP)和 I/O3(HOLD)。 SPI 最高支持 80MHz,當(dāng)用快讀雙倍/四倍指令時(shí),相當(dāng)于雙倍輸出時(shí)最高速率 160MHz,四倍輸出時(shí)最高速率 320MHz。這個(gè)傳輸速率比得上 8 位和 16 位的并行 Flash 存儲(chǔ)器。HOLD 引腳和寫保護(hù)引腳可編程寫保護(hù)。此外,芯片支持 JEDEC 標(biāo)準(zhǔn),具有唯一的 64 位識(shí)別序列號(hào)。

●SPI 串行存儲(chǔ)器系列
-W25Q64:64M 位/8M 字節(jié)
-W25Q16:16M 位/2M 字節(jié)
-W25Q32:32M 位/4M 字節(jié)
-每256字節(jié)可編程頁

2. 硬件環(huán)境

當(dāng)前測試使用的開發(fā)板采用友善之臂的Tiny4412開發(fā)板,芯片是三星的EXYNOS-4412,最高主頻1.5GHZ。

開發(fā)板引出了SPI的IO口,這里使用的W25Q64是外置的模塊,使用杜邦線與開發(fā)板的IO口連接。

開發(fā)板上引出的IO口都是5V和1.8V,為了方便供電,采用了一個(gè)USB轉(zhuǎn)TTL模塊提供電源,測試驅(qū)動(dòng)。

W25Q64模塊接在開發(fā)板的SPI0接口上面的。

image-20220106103405322

Linux內(nèi)核自帶有SPI子系統(tǒng)的設(shè)備端示例代碼:

Linux 內(nèi)核自帶的 SPI 驅(qū)動(dòng)注冊(cè)示例代碼: \drivers\spi\spidev.c
Linux 內(nèi)核自帶的 SPI APP 注冊(cè)示例代碼: \Documentation\spi

如果要使用內(nèi)核自帶SPI驅(qū)動(dòng),可以在內(nèi)核編譯時(shí)配置一下。

root# make menuconfig
Device Drivers  --->  
[*] SPI support  --->  
<*>   Samsung S3C64XX series type SPI                                          
	  [*]     Samsung S3C64XX Channel 0 Support.

Tiny4412自帶內(nèi)核里的SPI設(shè)備端結(jié)構(gòu):

image-20220106103638018

?

SPI0的具體GPIO口位置:

image-20220106103712723

3. 案例代碼

3.1 模擬SPI時(shí)序-編寫驅(qū)動(dòng)

下面是W25Q64的驅(qū)動(dòng)測試代碼,沒有注冊(cè)字符設(shè)備框架,只是在驅(qū)動(dòng)的入口里測試時(shí)序是否OK,打印了ID,讀寫了數(shù)據(jù)進(jìn)行測試。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

/*--------------------------------W25Q64相關(guān)操作代碼---------------------------------------------*/
/*定義指針,用于接收虛擬地址*/
volatile unsigned int *W25Q64_GPBCON;
volatile unsigned int *W25Q64_GPBDAT;
/*
函數(shù)功能:W25Q64初始化
Tiny4412硬件連接:
	DO--MISO :GPB_2 //輸入模式
	DI--MOSI :GPB_3 //輸出模式
	CLK-SCLK :GPB_0 //時(shí)鐘
	CS--CS   :GPB_1 //片選
*/
void W25Q64_Init(void)
{
	/*1. 初始化GPIO*/
	/*映射物理地址*/
	W25Q64_GPBCON=ioremap(0x11400040,4);
	W25Q64_GPBDAT=ioremap(0x11400044,4);
	
	*W25Q64_GPBCON &= ~(0xf  << 0 * 4);*W25Q64_GPBCON |=  (0x1   << 0 * 4);
	*W25Q64_GPBCON &= ~(0xf  << 1 * 4);*W25Q64_GPBCON |=  (0x1   << 1 * 4);
	*W25Q64_GPBCON &= ~(0xf  << 2 * 4);
	*W25Q64_GPBCON &= ~(0xf  << 3 * 4);*W25Q64_GPBCON |=  (0x1   << 3 * 4);
	
	/*2. 上拉GPIO口*/
	//*W25Q64_GPBDAT &= ~(1 << 4);//輸出0
	*W25Q64_GPBDAT |= (1 << 0);   //輸出1
	*W25Q64_GPBDAT |= (1 << 1);   //輸出1
	*W25Q64_GPBDAT |= (1 << 3);   //輸出1
}
/*
函數(shù)功能:SPI時(shí)序讀寫一個(gè)字節(jié)
說    明:SPI底層時(shí)序,程序的移植接口
*/
u8 W25Q64_SPI_ReadWriteOneByte(u8 data_tx)
{
	 u8 data_rx=0;
	 u8 i;
	 for(i=0;i<8;i++)
	 {
		*W25Q64_GPBDAT &= ~(1 << 0);//輸出0
		if(data_tx&0x80)*W25Q64_GPBDAT |= (1 << 3);   //輸出1
		else *W25Q64_GPBDAT &= ~(1 << 3);//輸出0
		data_tx<<=1; //繼續(xù)發(fā)送下一個(gè)數(shù)據(jù)

		*W25Q64_GPBDAT |= (1 << 0);   //輸出1
		data_rx<<=1;
		if((*W25Q64_GPBDAT & (1 << 2)))data_rx|=0x01;
	 }
	 return data_rx;
}

/*
函數(shù)功能:寫使能
*/
void  W25Q64_WriteEnabled(void)
{
	*W25Q64_GPBDAT &= ~(1 << 1); //選中W25Q64
	W25Q64_SPI_ReadWriteOneByte(0x06);
	*W25Q64_GPBDAT |= (1 << 1); //取消選中W25Q64
}
/*
函數(shù)功能:讀狀態(tài)
*/
void W25Q64_GetBusyStat(void)
{
	unsigned char stat=1;
	while(stat&0x01)  //判斷狀態(tài)最低位
	{
		*W25Q64_GPBDAT &= ~(1 << 1);
		W25Q64_SPI_ReadWriteOneByte(0x05);
		stat=W25Q64_SPI_ReadWriteOneByte(0xFF);  //讀取狀態(tài)寄存器的值
		*W25Q64_GPBDAT |= (1 << 1);
	}
}
/*
函數(shù)功能:讀取設(shè)備ID和制造商ID
W25Q64: EF16
W25QQ128:EF17
*/
unsigned short W25Q64_ReadDeviceID(void)
{
	unsigned short ID;
	*W25Q64_GPBDAT &= ~(1 << 1);
	W25Q64_SPI_ReadWriteOneByte(0x90);
	W25Q64_SPI_ReadWriteOneByte(0x0); 
	W25Q64_SPI_ReadWriteOneByte(0x0); 
	W25Q64_SPI_ReadWriteOneByte(0x0);

	ID=W25Q64_SPI_ReadWriteOneByte(0xFF)<<8; //制造商ID
	ID|=W25Q64_SPI_ReadWriteOneByte(0xFF);   //設(shè)備ID
	*W25Q64_GPBDAT |= (1 << 1);
	return ID;
}
/*
函數(shù)功能:全片擦除
*/
void W25Q64_ClearAll(void)
{
	W25Q64_WriteEnabled(); //寫使能
	W25Q64_GetBusyStat();  //檢測狀態(tài)寄存器
	*W25Q64_GPBDAT &= ~(1 << 1);
	W25Q64_SPI_ReadWriteOneByte(0xC7);
	*W25Q64_GPBDAT |= (1 << 1);
	W25Q64_GetBusyStat();  //檢測狀態(tài)寄存器
}
/*
函數(shù)功能:頁編程
參    數(shù):
		unsigned int addr:寫入的地址
        void  *p:將要寫入的數(shù)據(jù)
		unsigned int  len:寫入的長度
說    明:每次最多只能寫入256字節(jié)
*/
void W25Q64_PageWrite(unsigned int addr,void*p,unsigned int len)
{
	 unsigned short i;
	 unsigned char *buff=p;
	 W25Q64_WriteEnabled(); //寫使能
	 *W25Q64_GPBDAT &= ~(1 << 1);
	 W25Q64_SPI_ReadWriteOneByte(0x02);
	 W25Q64_SPI_ReadWriteOneByte(addr>>16); 
	 W25Q64_SPI_ReadWriteOneByte(addr>>8); 
	 W25Q64_SPI_ReadWriteOneByte((unsigned char)addr);
	 for(i=0;i>16); 
	W25Q64_SPI_ReadWriteOneByte(addr>>8); 
	W25Q64_SPI_ReadWriteOneByte((unsigned char)addr);
	*W25Q64_GPBDAT |= (1 << 1);
	W25Q64_GetBusyStat();  //檢測狀態(tài)寄存器
}
/*
函數(shù)功能:數(shù)據(jù)讀取
參    數(shù):
*/
void  W25Q64_ReadData(unsigned int addr,void *p,unsigned int len)
{
	unsigned int i=0;
	unsigned char *buff=p;
	*W25Q64_GPBDAT &= ~(1 << 1);
	W25Q64_SPI_ReadWriteOneByte(0x03);
	W25Q64_SPI_ReadWriteOneByte(addr>>16); 
	W25Q64_SPI_ReadWriteOneByte(addr>>8); 
	W25Q64_SPI_ReadWriteOneByte((unsigned char)addr);
	for(i=0;i256)page_remain=256;
		else page_remain=len;
	} 
}
/*
函數(shù)功能:在任意地址寫入任意數(shù)據(jù),對(duì)扇區(qū)進(jìn)行校驗(yàn)
參    數(shù):
	unsigned int addr:寫入數(shù)據(jù)的地址
	void *p :寫入的數(shù)據(jù)
	unsigned int len :寫入數(shù)據(jù)的長度
說明:一個(gè)扇區(qū)的空間4096字節(jié)
*/
unsigned char W25Q64_BUFF[1024*4]; //用來檢驗(yàn)一個(gè)扇區(qū)的數(shù)據(jù)是否需要擦除

void W25Q64_WriteData(unsigned int addr,void *p,unsigned int len)
{
	unsigned int sector_len=4096-addr%4096;  //剩余空間大小 
	unsigned char *buff=p;
	unsigned int i=0;
	if(len4096)
		{
			sector_len=4096;
		}
		else
		{
			sector_len=len;
		}
	}
}
static int __init w25q64_init(void)
{
	/*1. 初始化GPIO口*/
	W25Q64_Init();
	
	/*2. 打印廠商芯片ID*/
	unsigned short id=W25Q64_ReadDeviceID();
	printk("id=0x%X\n",id);
	
	/*3. 寫入數(shù)據(jù)*/
	char buff[]="W25Q64-test-123456789ABCDEFG";
	W25Q64_WriteData(100,buff,strlen(buff));
	printk("write-data:%s\n",buff);
	
	/*4. 讀出數(shù)據(jù)*/
	char buff_rx[100];
	W25Q64_ReadData(100,buff_rx,strlen(buff));
	printk("read-data:%s\n",buff_rx);
	return 0;
}
static void __exit w25q64_exit(void)
{
	/*釋放虛擬地址*/
	iounmap(W25Q64_GPBCON);
	iounmap(W25Q64_GPBDAT);
	printk("w25q64 driver exit ok!\n");
}

module_exit(w25q64_exit);
module_init(w25q64_init);
MODULE_LICENSE("GPL");
)>;i++)>;i++)>

3.2 采用SPI子系統(tǒng)框架-編寫驅(qū)動(dòng)

下面代碼使用SPI子系統(tǒng)框架編寫的驅(qū)動(dòng)測試代碼,注冊(cè)了字符設(shè)備框架,但是只是做了簡單的測試,目的只是測試W25Q64是否可以正常驅(qū)動(dòng),能讀寫存儲(chǔ)。

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include    /*雜項(xiàng)字符設(shè)備頭文件*/
#include            /*文件操作集合*/
#include 

/*--------------------------------W25Q64相關(guān)操作代碼---------------------------------------------*/
struct spi_device *w25q64_spi_Device;
/*
函數(shù)功能:W25Q64初始化
Tiny4412硬件連接:
	DO--MISO :GPB_2 //輸入模式
	DI--MOSI :GPB_3 //輸出模式
	CLK-SCLK :GPB_0 //時(shí)鐘
	CS--CS   :GPB_1 //片選
*/
/*
函數(shù)功能:讀取設(shè)備ID和制造商ID
W25Q64: EF16
W25QQ128:EF17

參數(shù):0x90表示讀取ID號(hào)的指令
*/
unsigned short W25Q64_ReadDeviceID(void)
{
	/*使用硬件SPI同步讀寫時(shí)序*/
	char tx_buf[6]={0x90,0x0,0x0,0x0,0xFF,0xFF};
	char rx_buf[6];

	struct spi_message m;
	struct spi_transfer t=
	{
		.tx_buf=tx_buf,
		.rx_buf=rx_buf,
		.len=6,
		.delay_usecs=0,
		.speed_hz=1000000,
		.bits_per_word=8
	};
	spi_message_init(&m);
	spi_message_add_tail(&t,&m);
	spi_sync(w25q64_spi_Device,&m);
	return rx_buf[4]<<8|rx_buf[5]; /*得到ID值*/
}
/*
函數(shù)功能:指定位置讀取指定長度的數(shù)據(jù)
參    數(shù):
0x03 表示讀取數(shù)據(jù)的指令。
*/
void  W25Q64_ReadData(unsigned int addr,void *p,unsigned int len)
{	
	/*使用硬件SPI同步讀寫時(shí)序*/
	char tx_buf[4];
	tx_buf[0]=0x03;       //讀指令
	tx_buf[1]=addr>>16;   //以下是地址指令
	tx_buf[2]=addr>>8;
	tx_buf[3]=addr;
	spi_write(w25q64_spi_Device,tx_buf,4);
	spi_read(w25q64_spi_Device,p,len);
}
/*
函數(shù)功能:寫使能
*/
void  W25Q64_WriteEnabled(void)
{
	/*使用硬件SPI同步讀寫時(shí)序*/
	char tx_buf[1]={0x06};
	struct spi_message m;
	struct spi_transfer t=
	{
		.tx_buf=tx_buf,
		.len=1,
		.delay_usecs=0,
		.speed_hz=1000000,
		.bits_per_word=8
	};
	spi_message_init(&m);
	spi_message_add_tail(&t,&m);
	spi_sync(w25q64_spi_Device,&m);
}
/*
函數(shù)功能:讀狀態(tài)
*/
void W25Q64_GetBusyStat(void)
{
	unsigned char stat=1;
	/*使用硬件SPI同步讀寫時(shí)序*/
	char tx_buf[2]={0x05,0xFF};
	char rx_buf[2];
	while(stat&0x01)  //判斷狀態(tài)最低位
	{	
		struct spi_message m;
		struct spi_transfer t=
		{
			.tx_buf=tx_buf,
			.rx_buf=rx_buf,
			.len=2,
			.delay_usecs=0,
			.speed_hz=1000000,
			.bits_per_word=8
		};
		spi_message_init(&m);
		spi_message_add_tail(&t,&m);
		spi_sync(w25q64_spi_Device,&m);
		stat=rx_buf[1]; //得到狀態(tài)寄存器
	}
}
/*
函數(shù)功能:扇區(qū)擦除
參    數(shù):
		unsigned int addr:扇區(qū)的地址
說   明:一個(gè)扇區(qū)是4096字節(jié),擦除一個(gè)扇區(qū)時(shí)間至少150ms
*/
void W25Q64_ClearSector(unsigned int addr)
{
	W25Q64_WriteEnabled(); //寫使能
	W25Q64_GetBusyStat();  //檢測狀態(tài)寄存器
	
	/*使用硬件SPI同步讀寫時(shí)序*/
	unsigned char tx_buf[4];
	tx_buf[0]=0x20;
	tx_buf[1]=addr>>16;
	tx_buf[2]=addr>>8;
	tx_buf[3]=addr;
	
	char rx_buf[4];
	struct spi_message m;
	struct spi_transfer t=
	{
		.tx_buf=tx_buf,
		.rx_buf=rx_buf,
		.len=4,
		.delay_usecs=0,
		.speed_hz=1000000,
		.bits_per_word=8
	};
	spi_message_init(&m);
	spi_message_add_tail(&t,&m);
	spi_sync(w25q64_spi_Device,&m);
	W25Q64_GetBusyStat();  //檢測狀態(tài)寄存器
}
/*
函數(shù)功能:頁編程
參    數(shù):
		unsigned int addr:寫入的地址
        void  *p:將要寫入的數(shù)據(jù)
		unsigned int  len:寫入的長度
說    明:每次最多只能寫入256字節(jié)
*/
void W25Q64_PageWrite(unsigned int addr,void*p,unsigned int len)
{
	 unsigned short i;
	 unsigned char *buff=p;
	 W25Q64_WriteEnabled(); //寫使能
	 
	/*使用硬件SPI同步讀寫時(shí)序*/
	unsigned char tx_buf[4];
	tx_buf[0]=0x02;       //頁寫指令
	tx_buf[1]=(addr>>16)&0xFF;   //以下是地址指令
	tx_buf[2]=(addr>>8)&0xFF;
	tx_buf[3]=(addr&0xFF);
	
	//寫數(shù)據(jù)
	spi_write(w25q64_spi_Device,tx_buf,4);
	//寫數(shù)據(jù)
	spi_write(w25q64_spi_Device,p,len);
	W25Q64_GetBusyStat();  //檢測狀態(tài)寄存器
}
/*
函數(shù)功能:在任意地址寫入任意數(shù)據(jù),不進(jìn)行校驗(yàn)
參    數(shù):
	unsigned int addr:寫入數(shù)據(jù)的地址
	void *p :寫入的數(shù)據(jù)
	unsigned int len :寫入數(shù)據(jù)的長度
*/
void W25Q64_WriteDataONCheck(unsigned int addr,void *p,unsigned int len)
{
	unsigned char *buff=p;
	unsigned short page_remain=256-addr%256;  //當(dāng)前地址開始一頁剩下的空間
	unsigned short remain_len;      //剩余未寫入的長度
	if(len256)page_remain=256;
		else page_remain=len;
	} 
}

/*
函數(shù)功能:在任意地址寫入任意數(shù)據(jù),對(duì)扇區(qū)進(jìn)行校驗(yàn)
參    數(shù):
	unsigned int addr:寫入數(shù)據(jù)的地址
	void *p :寫入的數(shù)據(jù)
	unsigned int len :寫入數(shù)據(jù)的長度
說明:一個(gè)扇區(qū)的空間4096字節(jié)
*/
static unsigned char W25Q64_BUFF[1024*4]; //用來檢驗(yàn)一個(gè)扇區(qū)的數(shù)據(jù)是否需要擦除
void W25Q64_WriteData(unsigned int addr,void *p,unsigned int len)
{
	unsigned int sector_len=4096-addr%4096;  //剩余空間大小 
	unsigned char *buff=p;
	unsigned int i=0;
	if(len4096)
		{
			sector_len=4096;
		}
		else
		{
			sector_len=len;
		}
	}
}
/*
雜項(xiàng)字符設(shè)備注冊(cè)示例----->LED
*/
static int tiny4412_open(struct inode *my_inode, struct file *my_file)
{
	return 0;
}

static int tiny4412_release(struct inode *my_inode, struct file *my_file)
{
	return 0;
}

static ssize_t tiny4412_read(struct file *my_file, char __user *buf, size_t len, loff_t *loff)
{
	/*2. 打印廠商芯片ID*/
	unsigned short id=W25Q64_ReadDeviceID();
	printk("-ID=0x%X\n",id);
	
	/*3. 寫入數(shù)據(jù)*/
	char buff[100]="打印廠商芯片ID打印廠商芯片ID";
	W25Q64_WriteData(0,buff,100);
	
	/*4. 讀出數(shù)據(jù)*/
	char buff_rx[100];
	W25Q64_ReadData(0,buff_rx,100);
	printk("Read=%s\n",buff_rx);
	return 0;
}
static ssize_t tiny4412_write(struct file *my_file, const char __user *buf, size_t len, loff_t *loff)
{
	return 0;
}

/*文件操作集合*/
static struct file_operations tiny4412_fops=
{
	.open=tiny4412_open,
	.read=tiny4412_read,
	.write=tiny4412_write,
	.release=tiny4412_release
};
/*
核心結(jié)構(gòu)體
*/
static struct miscdevice tiny4412_misc=
{
	.minor=MISC_DYNAMIC_MINOR,  /*自動(dòng)分配次設(shè)備號(hào)*/
	.name="tiny4412_W25q64",       /*設(shè)備文件,指定/dev/生成的文件名稱*/
	.fops=&tiny4412_fops
};
static int __devinit w25q64_probe(struct spi_device *spi)
{
	/*配置SPI模式*/
	spi->bits_per_word = 8;
	spi->mode = SPI_MODE_0;
	spi->max_speed_hz=1*1000000; //1Mhz	
	if(spi_setup(spi)<0)//配置
	{
		printk("SPI配置失敗!\n");
	}
	
	/*保存指針指向*/
	w25q64_spi_Device=spi;
	
	printk("w25q64 probe ok!\n");
	printk("SpiNum=%d\n",spi->dev.id);
	
	/*雜項(xiàng)設(shè)備注冊(cè)*/
    misc_register(&tiny4412_misc);
	return 0;
}
static int __devexit w25q64_remove(struct spi_device *spi)
{
	/*雜項(xiàng)設(shè)備注銷*/
	misc_deregister(&tiny4412_misc);
	return 0;
}
static struct spi_driver w25q64_spi_driver = {
	.driver = {
		.name =	"spidev",
		.owner =THIS_MODULE,
	},
	.probe =w25q64_probe,
	.remove = __devexit_p(w25q64_remove),
};
/*-------------------------------------------------------------------------*/
static int __init w25q64_init(void)
{
	spi_register_driver(&w25q64_spi_driver);
	printk("w25q64 driver install ok!\n");
	return 0;
}
static void __exit w25q64_exit(void)
{
	spi_unregister_driver(&w25q64_spi_driver);
	printk("w25q64 driver exit ok!\n");
}

module_exit(w25q64_exit);
module_init(w25q64_init);
MODULE_LICENSE("GPL");)>)>
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FlaSh
    +關(guān)注

    關(guān)注

    10

    文章

    1715

    瀏覽量

    154708
  • 驅(qū)動(dòng)
    +關(guān)注

    關(guān)注

    12

    文章

    1928

    瀏覽量

    88204
  • w25Q64
    +關(guān)注

    關(guān)注

    1

    文章

    15

    瀏覽量

    3223
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    Linux驅(qū)動(dòng)開發(fā)的必備知識(shí)

    、內(nèi)核模塊編程: 掌握內(nèi)核模塊的編寫、編譯、加載和卸載方法。 了解內(nèi)核模塊的初始化和清理函數(shù)的編寫。 5、設(shè)備驅(qū)動(dòng)框架: 熟悉字符設(shè)備、塊設(shè)備、網(wǎng)絡(luò)設(shè)備等驅(qū)動(dòng)框架。 能夠根據(jù)
    發(fā)表于 12-04 07:58

    FPGA實(shí)現(xiàn)基于SPI協(xié)議的Flash驅(qū)動(dòng)控制芯片擦除

    本篇博客具體包括SPI協(xié)議的基本原理、模式選擇以及時(shí)序邏輯要求,采用FPGA(EPCE4),通過SPI通信協(xié)議,對(duì)flashW25Q16BV)存儲(chǔ)的固化程序進(jìn)行芯片擦除操作。
    的頭像 發(fā)表于 12-02 10:00 ?1750次閱讀
    FPGA實(shí)現(xiàn)基于SPI協(xié)議的<b class='flag-5'>Flash</b><b class='flag-5'>驅(qū)動(dòng)</b>控制芯片擦除

    【免費(fèi)送書】成為硬核Linux開發(fā)者:《Linux 設(shè)備驅(qū)動(dòng)開發(fā)(第 2 版)》

    Linux系統(tǒng)的設(shè)備驅(qū)動(dòng)開發(fā),一直給人門檻較高的印象,主要因內(nèi)核機(jī)制抽象、需深度理解硬件原理、開發(fā)調(diào)試難度大所致。2021年,一本講解驅(qū)動(dòng)
    的頭像 發(fā)表于 11-18 08:06 ?439次閱讀
    【免費(fèi)送書】成為硬核<b class='flag-5'>Linux</b><b class='flag-5'>開發(fā)</b>者:《<b class='flag-5'>Linux</b> 設(shè)備<b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>開發(fā)</b>(第 2 版)》

    【書籍評(píng)測活動(dòng)NO.67】成為硬核Linux開發(fā)者:《Linux 設(shè)備驅(qū)動(dòng)開發(fā)(第 2 版)》

    ,開發(fā)設(shè)備驅(qū)動(dòng)和板級(jí)支持包。截至目前,Linux仍是嵌入式系統(tǒng)領(lǐng)域的主流內(nèi)核,幾乎廣泛應(yīng)用于工業(yè)界的所有領(lǐng)域,這主要得益于其功能強(qiáng)大的子系統(tǒng)。因此,約翰·馬迪厄編寫本書,向廣大
    發(fā)表于 11-17 17:52

    W25Q128JVSIM與GD25Q128ESIGR引腳兼容分析

    華邦W25Q128JVSIM作為常用的128Mbit SPI NOR Flash芯片,其兼容替代方案兆易創(chuàng)新GD25Q128ESIGR已獲得批量客戶的認(rèn)可及使用。
    的頭像 發(fā)表于 10-13 09:33 ?633次閱讀
    <b class='flag-5'>W25Q</b>128JVSIM與GD<b class='flag-5'>25Q</b>128ESIGR引腳兼容分析

    SFUD QSPI讀寫w25q64jv失敗是什么原因?qū)е碌模?/a>

    rtthread 版本: 5.1.0 芯片: stm32H743XI, 接口 qspi 20MHz Flash: w25q64jv 第一次上電能正常讀取到ID, 但是只有這一次成功, 之后就都是0
    發(fā)表于 09-29 07:37

    如何在rtt studio中進(jìn)行外部flash的調(diào)試?

    app下載到了外部flashw25q64)程序可以運(yùn)行但調(diào)試不了
    發(fā)表于 09-25 07:53

    華邦電子W25Q-RV系列NOR Flash的四大本領(lǐng)

    在汽車、物聯(lián)網(wǎng)和工業(yè)自動(dòng)化等應(yīng)用場景中,存儲(chǔ)器是否能夠穩(wěn)定運(yùn)行直接影響產(chǎn)品的可靠性。華邦推出的 W25Q-RV 系列 NOR Flash,成功通過 105°C 的工業(yè)級(jí)高溫循環(huán)測試和儲(chǔ)能測試,以超越 JEDEC 標(biāo)準(zhǔn)的性能,在嚴(yán)苛環(huán)境下為產(chǎn)品保駕護(hù)航。
    的頭像 發(fā)表于 08-16 17:14 ?1353次閱讀

    GD25Q64ESIG寬溫導(dǎo)航芯

    兆易創(chuàng)新GD25Q64ESIG NOR FLASH憑借64Mb容量、8Mbx8架構(gòu)及2.7V 3.6V寬電壓支持,其SOP 8封裝適配緊湊設(shè)計(jì),高速SPI接口(133MHz)確??焖贁?shù)據(jù)讀取,滿足
    的頭像 發(fā)表于 08-07 09:45 ?756次閱讀
    GD<b class='flag-5'>25Q64</b>ESIG寬溫導(dǎo)航芯

    W25X16W25X32\W25X64 數(shù)據(jù)手冊(cè)

    電子發(fā)燒友網(wǎng)站提供《W25X16W25X32\W25X64 數(shù)據(jù)手冊(cè).pdf》資料免費(fèi)下載
    發(fā)表于 07-10 16:10 ?4次下載

    itop-3568開發(fā)驅(qū)動(dòng)開發(fā)指南-實(shí)驗(yàn)程序的編寫

    本實(shí)驗(yàn)對(duì)應(yīng)的網(wǎng)盤路徑為:iTOP-RK3568 開發(fā)板【底板 V1.7 版本】\\\\03_【iTOP-RK3568開發(fā)板】指南教程\\\\02_Linux 驅(qū)動(dòng)配套資料\\\\04_
    發(fā)表于 05-19 10:26

    DLPC3479上電初始化失敗的原因?

    我們做了兩塊電路板,使用DLPC3479驅(qū)動(dòng)光機(jī),3005作為電源,使用W25Q64作為FLASH。接上光機(jī)之后,上電發(fā)現(xiàn)3005的1.1V,1.8V,3.3V均輸出正常,-14V,10V,18V
    發(fā)表于 02-21 10:05

    DLPC3479上電初始化失敗的原因?

    使用DLPC3479驅(qū)動(dòng)光機(jī),3005作為電源,使用W25Q64作為FLASH。接上光機(jī)之后,上電發(fā)現(xiàn)3005的1.1V,1.8V,3.3V均輸出正常,-14V,10V,18V電壓輸出后掉下來
    發(fā)表于 02-21 06:44

    迅為RK3568開發(fā)驅(qū)動(dòng)指南Linux中通用SPI設(shè)備驅(qū)動(dòng)

    迅為RK3568開發(fā)驅(qū)動(dòng)指南Linux中通用SPI設(shè)備驅(qū)動(dòng)
    的頭像 發(fā)表于 01-23 11:02 ?3433次閱讀
    迅為RK3568<b class='flag-5'>開發(fā)</b>板<b class='flag-5'>驅(qū)動(dòng)</b>指南<b class='flag-5'>Linux</b>中通用SPI設(shè)備<b class='flag-5'>驅(qū)動(dòng)</b>

    迅為RK3568開發(fā)板SPI驅(qū)動(dòng)指南-mcp2515驅(qū)動(dòng)編寫:讀寄存器函數(shù)

    迅為RK3568開發(fā)板SPI驅(qū)動(dòng)指南-mcp2515驅(qū)動(dòng)編寫:讀寄存器函數(shù)
    的頭像 發(fā)表于 01-20 14:43 ?1505次閱讀
    迅為RK3568<b class='flag-5'>開發(fā)</b>板SPI<b class='flag-5'>驅(qū)動(dòng)</b>指南-mcp2515<b class='flag-5'>驅(qū)動(dòng)</b><b class='flag-5'>編寫</b>:讀寄存器函數(shù)