Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

271 linhas
8.3 KiB

/*******************************************************************************
 * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
 * @file     w25qxx.c
 * @author   UartTFT Application Team
 * @version  V1.0.0
 * @date     2023-02-24
 * @brief	 Nor Flash Library Functions
 ********************************************************************************/
#include "w25qxx.h"
uint8_t W25Q256 = 0;
/********************************************************************************
* Function Name	: LT_W25qxx_ReadSR
* Description  	: Read the value of the register.
* Input        	: - SRx:Register address
				  - 3 status registers
				  - W25X_READ_SR1: address 0x05
							 BIT   7   6   5   4   3   2   1   0
								  SPR  RV TB  BP2  BP1 BP0 WEL BUSY
				  - W25X_READ_SR2: address 0x35
				  - W25X_READ_SR3: address 0x15
* Output       	: None
* Return       	: None
*********************************************************************************/
uint8_t LT_W25qxx_ReadSR(void)
{
	uint8_t byte = 0;
	nSS_Active();
	SPI_Master_FIFO_Data_Put(W25X_ReadStatusReg);
	byte = SPI_Master_FIFO_Data_Put(0Xff);
	nSS_Inactive();
	return byte;
}
/********************************************************************************
 * Function Name	: LT_W25qxx_Write_Enable
 * Description  	: Write Enable(set WEL to 1).
 * Input        	: None
 * Output       	: None
 * Return       	: None
 *********************************************************************************/
void LT_W25qxx_Write_Enable(void)
{
	nSS_Active();
	SPI_Master_FIFO_Data_Put(W25X_WriteEnable);
	nSS_Inactive();
}
/********************************************************************************
 * Function Name	: LT_W25QXX_Write_Disable
 * Description  	: Write Disable
 * Input        	: None
 * Output       	: None
 * Return       	: None
 *********************************************************************************/
void LT_W25QXX_Write_Disable(void)
{
	nSS_Active();
	SPI_Master_FIFO_Data_Put(W25X_WriteDisable);
	nSS_Inactive();
}
/********************************************************************************
 * Function Name	: LT_W25qxx_Wait_Busy
 * Description  	: Wait for BUSY bit to clear.
 * Input        	: None
 * Output       	: None
 * Return       	: None
 *********************************************************************************/
void LT_W25qxx_Wait_Busy(void)
{
	while ((LT_W25qxx_ReadSR() & 0x01) == 0x01)
		;
}
/********************************************************************************
 * Function Name	: LT_W25qxx_ReadID
 * Description  	: Read W25qxx ID.
 * Input        	: None
 * Output       	: None
 * Return       	: Flash ID
 *********************************************************************************/
uint16_t LT_W25qxx_ReadID(void)
{
	uint16_t Temp = 0;
	nSS_Active();
	SPI_Master_FIFO_Data_Put(W25X_ManufactDeviceID);
	SPI_Master_FIFO_Data_Put(0x00);
	SPI_Master_FIFO_Data_Put(0x00);
	SPI_Master_FIFO_Data_Put(0x00);
	Temp |= SPI_Master_FIFO_Data_Put(0xFF) << 8;
	Temp |= SPI_Master_FIFO_Data_Put(0xFF);
	nSS_Inactive();
	return Temp;
}
/********************************************************************************
* Function Name	: LT_W25qxx_Read
* 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_W25qxx_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
	uint16_t i;
	nSS_Active();
	SPI_Master_FIFO_Data_Put(W25X_ReadData);
	if (W25Q256)
		SPI_Master_FIFO_Data_Put((uint8_t)((ReadAddr) >> 24));
	SPI_Master_FIFO_Data_Put((uint8_t)((ReadAddr) >> 16));
	SPI_Master_FIFO_Data_Put((uint8_t)((ReadAddr) >> 8));
	SPI_Master_FIFO_Data_Put((uint8_t)ReadAddr);
	for (i = 0; i < NumByteToRead; i++)
	{
		pBuffer[i] = SPI_Master_FIFO_Data_Put(0XFF);
	}
	nSS_Inactive();
}
/********************************************************************************
* Function Name	: LT_W25QXX_Write_Page
* Description  	: On a page, write data of specified length at the specified address.
* Input        	: - pBuffer: data start address
				  - WriteAddr: Start address of writing data
				  - NumByteToWrite: number bytes to write(max one page:256 bytes)
* Output       	: None
* Return       	: None
*********************************************************************************/
void LT_W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
	uint16_t i;
	LT_W25qxx_Write_Enable();
	nSS_Active();
	SPI_Master_FIFO_Data_Put(W25X_PageProgram);
	if (W25Q256)
		SPI_Master_FIFO_Data_Put((uint8_t)((WriteAddr) >> 24));
	SPI_Master_FIFO_Data_Put((uint8_t)((WriteAddr) >> 16));
	SPI_Master_FIFO_Data_Put((uint8_t)((WriteAddr) >> 8));
	SPI_Master_FIFO_Data_Put((uint8_t)WriteAddr);
	LCD_CmdWrite(0xB8);
	SS_RESET;
	SPI2_ReadWriteByte(0x80);
	for (i = 0; i < NumByteToWrite; i++)
	{
		SPI2_ReadWriteByte(pBuffer[i]);
	}
	SS_SET;
	nSS_Inactive();
	LT_W25qxx_Wait_Busy();
}
/********************************************************************************
* Function Name	: LT_W25qxx_Write
* Description  	: Write SPI FLASH without inspection.
				  You must ensure that all the data written in the address range is 0XFF, otherwise the data written in non-0XFF will fail.
				  With auto-feed function
* Input        	: - LT_W25qxx_Write: data start address
				  - WriteAddr: Start address of writing data
				  - NumByteToWrite: number bytes to write(max 0xFFFF bytes)
* Output       	: None
* Return       	: None
*********************************************************************************/
void LT_W25qxx_Write(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
	uint16_t pageremain;
	pageremain = 256 - WriteAddr % 256;
	if (NumByteToWrite <= pageremain)
		pageremain = NumByteToWrite;
	while (1)
	{
		LT_W25QXX_Write_Page(pBuffer, WriteAddr, pageremain);
		if (NumByteToWrite == pageremain)
			break;
		else
		{
			pBuffer += pageremain;
			WriteAddr += pageremain;
			NumByteToWrite -= pageremain;
			if (NumByteToWrite > 256)
				pageremain = 256;
			else
				pageremain = NumByteToWrite;
		}
	}
}
/********************************************************************************
 * Function Name	: LT_W25qxx_Erase_Chip
 * Description  	: Full Erase.
 * Input        	: None
 * Output       	: None
 * Return       	: None
 *********************************************************************************/
void LT_W25qxx_Erase_Chip(void)
{
	LT_W25qxx_Write_Enable();
	LT_W25qxx_Wait_Busy();
	nSS_Active();
	SPI_Master_FIFO_Data_Put(W25X_ChipErase);
	nSS_Inactive();
	LT_W25qxx_Wait_Busy();
}
/********************************************************************************
 * Function Name	: LT_W25qxx_Erase_Sector
 * Description  	: Erase a sector (4*1024 bytes).
 * Input        	: - addr:sector address
 * Output       	: None
 * Return       	: None
 *********************************************************************************/
void LT_W25qxx_Erase_Sector(uint32_t Dst_Addr)
{
	Dst_Addr *= 4096;
	LT_W25qxx_Write_Enable();
	LT_W25qxx_Wait_Busy();
	nSS_Active();
	SPI_Master_FIFO_Data_Put(W25X_SectorErase);
	if (W25Q256)
		SPI_Master_FIFO_Data_Put((uint8_t)((Dst_Addr) >> 24));
	SPI_Master_FIFO_Data_Put((uint8_t)((Dst_Addr) >> 16));
	SPI_Master_FIFO_Data_Put((uint8_t)((Dst_Addr) >> 8));
	SPI_Master_FIFO_Data_Put((uint8_t)Dst_Addr);
	nSS_Inactive();
	LT_W25qxx_Wait_Busy();
}
/********************************************************************************
 * Function Name	: LT_W25qxx_BlockErase64KB
 * Description  	: Erase a block (64*1024 bytes).
 * Input        	: - addr:block address
 * Output       	: None
 * Return       	: None
 *********************************************************************************/
void LT_W25qxx_BlockErase64KB(uint32_t addr)
{
	addr *= 65536;
	LT_W25qxx_Write_Enable();
	LT_W25qxx_Wait_Busy();
	nSS_Active();
	SPI_Master_FIFO_Data_Put(W25X_BlockErase);
	if (W25Q256)
		SPI_Master_FIFO_Data_Put((uint8_t)((addr) >> 24));
	SPI_Master_FIFO_Data_Put((uint8_t)((addr) >> 16));
	SPI_Master_FIFO_Data_Put((uint8_t)((addr) >> 8));
	SPI_Master_FIFO_Data_Put((uint8_t)addr);
	nSS_Inactive();
	LT_W25qxx_Wait_Busy();
}
void LT_W25QXX_Enter_4Byte_AddressMode(void)
{
	nSS_Active();
	SPI_Master_FIFO_Data_Put(0xB7);
	nSS_Inactive();
}