Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

322 Zeilen
10 KiB

/*******************************************************************************
 * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
 * @file     w25n01.c
 * @author   UartTFT Application Team
 * @version  V1.0.0
 * @date     2023-02-24
 * @brief	 Nand Flash Library Functions
 ********************************************************************************/
#include "w25n01.h"
#include "LT768.h"
#include "LT768_Lib.h"
#include "dmac_drv.h"
#include "if_port.h"
/********************************************************************************
* Function Name	: W25N01GV_ReadID
* Description  	: Read W25N01GV ID.
* Input        	: None
* Output       	: None
* Return       	: Flash ID
*********************************************************************************/
uint32_t W25N01GV_ReadID(void)
{
	uint8_t Mfr_id = 0;
	uint8_t Device_idL = 0;
	uint8_t Device_idH = 0;
	uint32_t id = 0;
	nSS_Active();					
	SPI_Master_FIFO_Data_Put(0x9f); 
	SPI_Master_FIFO_Data_Put(0xff); 
	Mfr_id = SPI_Master_FIFO_Data_Put(0xff);
	Device_idH = SPI_Master_FIFO_Data_Put(0xff);
	Device_idL = SPI_Master_FIFO_Data_Put(0xff);
	nSS_Inactive();
	id = Mfr_id;
	id = (id << 8) + Device_idH;
	id = (id << 8) + Device_idL; 
	return id;
}
/********************************************************************************
* Function Name	: W25N01GV_Write_Enable
* Description  	: Enable to write.
* Input        	: None
* Output       	: None
* Return       	: None
*********************************************************************************/
void W25N01GV_Write_Enable(void)
{
	nSS_Active();									
	SPI_Master_FIFO_Data_Put(W25N01GV_WriteEnable); 
	nSS_Inactive();									
}
/********************************************************************************
* Function Name	: W25N01GV_Write_Disable
* Description  	: Disable to write.
* Input        	: None
* Output       	: None
* Return       	: None
*********************************************************************************/
void W25N01GV_Write_Disable(void)
{
	nSS_Active();									
	SPI_Master_FIFO_Data_Put(W25N01GV_WriteDisable); 
	nSS_Inactive();									
}
/********************************************************************************
* Function Name	: W25N01GV_Write_SR
* Description  	: Write the value of the register.
* Input        	: - SRx:Register address
				  - 3 status registers
				  - Protection register 1:    address 0xA0
				  - Configuration register 2: address 0xB0
				  - Status register 3:        address 0xC0  (Read Only)	
* Output       	: None
* Return       	: None
*********************************************************************************/
void W25N01GV_Write_SR(uint8_t reg, uint8_t val)
{
	nSS_Active();									   // Enable
	SPI_Master_FIFO_Data_Put(W25N01GV_WriteStatusReg); // Send write status register command
	SPI_Master_FIFO_Data_Put(reg);					   // Register address
	SPI_Master_FIFO_Data_Put(val);					   // Write a byte
	nSS_Inactive();									   // Disable
}
/********************************************************************************
* Function Name	: W25N01GV_ReadSR
* Description  	: Read the value of the register.
* Input        	: - SRx:Register address
				  - 3 status registers
				  - Protection register 1:    address 0xA0
				  - Configuration register 2: address 0xB0
				  - Status register 3:        address 0xC0  (Read Only)	
* Output       	: None
* Return       	: None
*********************************************************************************/
uint8_t W25N01GV_ReadSR(uint8_t reg)
{
	uint8_t byte = 0;
	nSS_Active();									  // Enable
	SPI_Master_FIFO_Data_Put(W25N01GV_ReadStatusReg); // Send read status register command
	SPI_Master_FIFO_Data_Put(reg);					  // Register address
	byte = SPI_Master_FIFO_Data_Put(0Xff);			  // Read a byte
	nSS_Inactive();									  // Disable
	return byte;
}
/********************************************************************************
* Function Name	: W25N01GV_Wait_Busy
* Description  	: Wait for BUSY bit to clear.
* Input        	: None
* Output       	: None
* Return       	: None
*********************************************************************************/
void W25N01GV_Wait_Busy(void)
{
	while ((W25N01GV_ReadSR(0xC0) & 0x01) == 0x01)
		; // Wait for BUSY bit to clear
}
/********************************************************************************
* Function Name	: W25N01GV_Erase_Block
* Description  	: W25N01 block erase(128K)
* Input        	: block : block num
* Output       	: None
* Return       	: None
*********************************************************************************/
void W25N01GV_Erase_Block(uint16_t block)
{
	uint16_t addr = 0;
	addr = 64 * block;
	W25N01GV_Write_SR(0xa0, 0x00); // Turn off flash protection function
	W25N01GV_Write_Enable(); // SET WEL
	W25N01GV_Wait_Busy();
	nSS_Active();					// Enable 
	SPI_Master_FIFO_Data_Put(0xD8); // Send chip erase command
	SPI_Master_FIFO_Data_Put(0xff); // Send chip erase command
	SPI_Master_FIFO_Data_Put((uint8_t)(addr >> 8));
	SPI_Master_FIFO_Data_Put((uint8_t)(addr));
	nSS_Inactive(); // Disable
	W25N01GV_Wait_Busy();		   // Wait for chip erase to finish
	W25N01GV_Write_SR(0xa0, 0x7c); // Turn on flash protection function
}
/********************************************************************************
* Function Name	: LT_W25N01GV_STD_Write_Page_DMA
* Description  	: Write data at the specified address of W25N01
* Input        	: - pBuffer: data start address
                  - PageNum: page
                  - PageAddr: Page address
                  - NumByteToWrite: number bytes to write(max one page:2048 bytes)
* Output       	: None
* Return       	: None
*********************************************************************************/
void W25N01GV_WritePageAddr_Data(uint8_t *pBuffer, uint32_t PageNum, uint32_t PageAddr, uint16_t NumByteToWrite)
{
	uint16_t i;
	// W25N01GV_Erase_Block(WriteAddr);
	W25N01GV_Write_SR(0xa0, 0x00); // Turn off flash protection function
	//------дBUFF------
	W25N01GV_Write_Enable();		// SET WEL
	nSS_Active();					// Enabling device
	SPI_Master_FIFO_Data_Put(0x02); // Send the write BUFF command
	SPI_Master_FIFO_Data_Put((PageAddr) >> 8); // BUFF address
	SPI_Master_FIFO_Data_Put(PageAddr);
	LCD_CmdWrite(0xB8);
	SS_RESET;
	SPI2_ReadWriteByte(0x80);
	for (i = 0; i < NumByteToWrite; i++)
		SPI2_ReadWriteByte(pBuffer[i]); // Number of cyclic writes
	SS_SET;
	nSS_Inactive();		  // Cancel film selection
	W25N01GV_Wait_Busy(); // Wait for writing to end
	//-------BUFF data writing flash--------
	W25N01GV_Write_Enable();
	nSS_Active();											
	SPI_Master_FIFO_Data_Put(0x10);							// Send page write command
	SPI_Master_FIFO_Data_Put(0xff);							// Send 16it address
	SPI_Master_FIFO_Data_Put((uint8_t)((PageNum) >> 8)); 	// Send 16it address
	SPI_Master_FIFO_Data_Put((uint8_t)(PageNum));
	nSS_Inactive();
	W25N01GV_Wait_Busy(); // Wait for writing to end
	W25N01GV_Write_SR(0xa0, 0x7c); // Turn on flash protection function
}
/********************************************************************************
* Function Name	: W25N01GV_ReadPageAddr_Data
* Description  	: Read data of specified length from the specified address.
* Input        	: - pBuffer: buffer for save data
                  - ReadAddr: Start address of reading data
                  - NumByteToRead: number bytes to read
* Output       	: None
* Return       	: None
*********************************************************************************/
void W25N01GV_ReadPageAddr_Data(uint8_t *pBuffer, uint32_t PageNum, uint32_t PageAddr, uint16_t NumByteToRead)
{
	uint16_t i;
	nSS_Active(); 
	SPI_Master_FIFO_Data_Put(0x13);
	SPI_Master_FIFO_Data_Put(0x00);
	SPI_Master_FIFO_Data_Put((uint8_t)((PageNum) >> 8)); 
	SPI_Master_FIFO_Data_Put((uint8_t)(PageNum));
	nSS_Inactive();
	W25N01GV_Wait_Busy();
	W25N01GV_Write_SR(0xb0, W25N01GV_ReadSR(0xb0) | 0x08); 
	nSS_Active();
	SPI_Master_FIFO_Data_Put(0x03);
	SPI_Master_FIFO_Data_Put((PageAddr) >> 8);
	SPI_Master_FIFO_Data_Put(PageAddr);
	SPI_Master_FIFO_Data_Put(0x00);
	SPI_CmdWrite(0xB8);
	for (i = 0; i < NumByteToRead; i++)
	{
		SPI_DataWrite(0xFF);			
		pBuffer[i] = SPI_DataRead();
	}
	nSS_Active(); //---------------------
	LT768_SPI_Init(1, 1);
	W25N01GV_Wait_Busy();
}
/********************************************************************************
* Function Name	: W25N01GV_ReadPageAddr_Data
* Description  	: Read data of specified length from the specified address.
* Input        	: - pBuffer: buffer for save data
                  - ReadAddr: Start address of reading data
                  - NumByteToRead: number bytes to read
* Output       	: None
* Return       	: None
*********************************************************************************/
void LT_W25N01_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) 
{
	uint16_t i;
	uint16_t page, endpage, remainder;
	remainder = ReadAddr % 2048;				   
	page = (ReadAddr / 2048);					   
	endpage = ((ReadAddr + NumByteToRead) / 2048); 
	LT768_SPI_Init(1, 1);
	if (page == endpage)
	{
		W25N01GV_ReadPageAddr_Data(pBuffer, page, remainder, NumByteToRead);
	}
	else
	{
		W25N01GV_ReadPageAddr_Data(pBuffer, page, remainder, 2048 - remainder);
		for (i = 1; page + i < endpage; i++)
		{
			W25N01GV_ReadPageAddr_Data(&pBuffer[2048 * i - remainder], page + i, 0, 2048);
		}
		W25N01GV_ReadPageAddr_Data(&pBuffer[2048 * i - remainder], endpage, 0, NumByteToRead - (2048 * i - remainder));
	}
}
void Write_Page(uint16_t page)
{
	nSS_Active();
	SPI_Master_FIFO_Data_Put(0x13);
	SPI_Master_FIFO_Data_Put(0x00);
	SPI_Master_FIFO_Data_Put((uint8_t)(page >> 8));
	SPI_Master_FIFO_Data_Put((uint8_t)page);
	nSS_Inactive();
	W25N01GV_Wait_Busy();
}
// Configure BUF=1: continuous read mode
void W25N01GV_ContinuousRead_Mode(void)
{
	uint8_t statut = 0;
	statut = W25N01GV_ReadSR(0xb0);
	statut &= cClrb3;
	statut &= cClrb4;
	statut |= cSetb4;
	W25N01GV_Write_SR(0xb0, statut);
}
// Configure BUF=0: page reading mode
void W25N01GV_PageRead_Mode(void)
{
	uint8_t statut = 0;
	statut = W25N01GV_ReadSR(0xb0);
	statut |= cSetb3;
	statut |= cSetb4;
	W25N01GV_Write_SR(0xb0, statut);
}
void W25N01GV_BUF1Set(void)
{
	uint8_t statut = 0;
	statut = W25N01GV_ReadSR(0xb0);
	statut |= cSetb3;
	statut &= cClrb4;
	//	statut |= cSetb4;
	W25N01GV_Write_SR(0xb0, statut);
}