You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

257 lines
7.5 KiB
C

#include "SWM221.h"
#include "W25N01G.h"
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: W25N01G_Init()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: W25N01G <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
void W25N01G_Init(void)
{
SPI_InitStructure SPI_initStruct;
GPIO_Init(GPIOB, PIN15, 1, 0, 0, 0);
#define W25N01G_Assert() GPIO_ClrBit(GPIOB, PIN15)
#define W25N01G_Deassert() GPIO_SetBit(GPIOB, PIN15)
W25N01G_Deassert();
PORT_Init(PORTB, PIN10, PORTB_PIN10_SPI0_SCLK, 0);
PORT_Init(PORTB, PIN13, PORTB_PIN13_SPI0_MOSI, 0);
PORT_Init(PORTB, PIN14, PORTB_PIN14_SPI0_MISO, 1);
SPI_initStruct.clkDiv = SPI_CLKDIV_32;
SPI_initStruct.FrameFormat = SPI_FORMAT_SPI;
SPI_initStruct.SampleEdge = SPI_FIRST_EDGE;
SPI_initStruct.IdleLevel = SPI_LOW_LEVEL;
SPI_initStruct.WordSize = 8;
SPI_initStruct.Master = 1;
SPI_initStruct.RXThreshold = 0;
SPI_initStruct.RXThresholdIEn = 0;
SPI_initStruct.TXThreshold = 0;
SPI_initStruct.TXThresholdIEn = 0;
SPI_initStruct.TXCompleteIEn = 0;
SPI_Init(SPI0, &SPI_initStruct);
SPI_Open(SPI0);
uint8_t reg = W25N01G_ReadReg(W25N_STATUS_REG2);
reg &= ~(1 << W25N_STATUS_REG2_BUF_Pos); // Continuous Read Mode
W25N01G_WriteReg(W25N_STATUS_REG2, reg);
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: W25N01G_ReadJEDEC()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: W25N01G <EFBFBD><EFBFBD>ȡ JEDEC ID
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
uint32_t W25N01G_ReadJEDEC(void)
{
uint8_t manufacture_id;
uint16_t device_id;
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_READ_JEDEC);
SPI_ReadWrite(SPI0, 0x00);
manufacture_id = SPI_ReadWrite(SPI0, 0xFF);
device_id = SPI_ReadWrite(SPI0, 0xFF) << 8;
device_id |= SPI_ReadWrite(SPI0, 0xFF);
W25N01G_Deassert();
return (manufacture_id << 16) | device_id;
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: W25N01G_Erase()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: W25N01G <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>СΪ 128KB
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: uint32_t addr Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SPI Flash <EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 128KB <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> addr <EFBFBD><EFBFBD> 0x20000 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* uint8_t wait <EFBFBD>Ƿ<EFBFBD><EFBFBD>ȴ<EFBFBD> SPI Flash <EFBFBD><EFBFBD><EFBFBD>ɲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1 <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
void W25N01G_Erase(uint32_t addr, uint8_t wait)
{
uint32_t page_addr = addr >> 12;
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_WRITE_ENABLE);
W25N01G_Deassert();
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_ERASE_BLOCK128KB);
SPI_ReadWrite(SPI0, (page_addr >> 16) & 0xFF);
SPI_ReadWrite(SPI0, (page_addr >> 8) & 0xFF);
SPI_ReadWrite(SPI0, (page_addr >> 0) & 0xFF);
W25N01G_Deassert();
if(wait)
while(W25N01G_FlashBusy()) __NOP();
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: W25N01G_Write()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: W25N01G ҳд<EFBFBD>ҳ<EFBFBD><EFBFBD>СΪ 2112 Byte
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: uint32_t addr Ҫд<EFBFBD><EFBFBD><EFBFBD> SPI Flash <EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0x1000<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 4096<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* uint8_t buff[2048] Ҫд<EFBFBD><EFBFBD> SPI Flash <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2048 <EFBFBD>ֽڣ<EFBFBD>ECC <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
void W25N01G_Write(uint32_t addr, uint8_t buff[2048])
{
uint32_t page_addr = addr >> 12;
uint16_t column_addr = 0x00;
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_WRITE_ENABLE);
W25N01G_Deassert();
/* Load the program data into the Data Buffer */
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_PAGE_PROGRAM);
SPI_ReadWrite(SPI0, (column_addr >> 8) & 0xFF);
SPI_ReadWrite(SPI0, (column_addr >> 0) & 0xFF);
for(int i = 0; i < 2048; i++)
{
SPI_ReadWrite(SPI0, buff[i]);
}
W25N01G_Deassert();
/* Program the Data Buffer content into the physical memory page */
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_PROGRAM_EXECUTE);
SPI_ReadWrite(SPI0, (page_addr >> 16) & 0xFF);
SPI_ReadWrite(SPI0, (page_addr >> 8) & 0xFF);
SPI_ReadWrite(SPI0, (page_addr >> 0) & 0xFF);
W25N01G_Deassert();
while(W25N01G_FlashBusy()) __NOP();
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: W25N01G_Read()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: W25N01G ҳ<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ҳ<EFBFBD><EFBFBD>СΪ 2112 Byte
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: uint32_t addr Ҫ<EFBFBD><EFBFBD>ȡ<EFBFBD>Ե<EFBFBD> SPI Flash <EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0x1000<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 4096<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* uint8_t buff[2048] <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2048 <EFBFBD>ֽڣ<EFBFBD>ECC <EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><EFBFBD><EFBFBD>ȡ
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
void W25N01G_Read(uint32_t addr, uint8_t buff[2048])
{
uint32_t page_addr = addr >> 12;
/* Transfer the data of specified page into the 2112-Byte Data Buffer */
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_PAGE_READ);
SPI_ReadWrite(SPI0, (page_addr >> 16) & 0xFF);
SPI_ReadWrite(SPI0, (page_addr >> 8) & 0xFF);
SPI_ReadWrite(SPI0, (page_addr >> 0) & 0xFF);
W25N01G_Deassert();
while(W25N01G_FlashBusy()) __NOP();
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_FAST_READ);
SPI_ReadWrite(SPI0, 0x00);
SPI_ReadWrite(SPI0, 0x00);
SPI_ReadWrite(SPI0, 0x00);
SPI_ReadWrite(SPI0, 0x00);
for(int i = 0; i < 2048; i++)
{
buff[i] = SPI_ReadWrite(SPI0, 0xFF);
}
W25N01G_Deassert();
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: W25N01G_FlashBusy()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: W25N01G æ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
bool W25N01G_FlashBusy(void)
{
uint8_t reg = W25N01G_ReadReg(W25N_STATUS_REG3);
bool busy = (reg & (1 << W25N_STATUS_REG3_BUSY_Pos));
return busy;
}
/******************************************************************************************************************************************
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: W25N01G_FlashProtect()
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD>: W25N01G д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
* ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>
******************************************************************************************************************************************/
void W25N01G_FlashProtect(uint8_t protect)
{
uint8_t tb = (protect >> 4);
uint8_t bp = (protect & 0xF);
uint8_t reg = W25N01G_ReadReg(W25N_STATUS_REG1);
reg &= ~(W25N_STATUS_REG1_TB_Msk | W25N_STATUS_REG1_BP_Msk | W25N_STATUS_REG1_WPE_Msk);
reg |= (tb << W25N_STATUS_REG1_TB_Pos) |
(bp << W25N_STATUS_REG1_BP_Pos);
W25N01G_WriteReg(W25N_STATUS_REG1, reg);
}
void W25N01G_WriteReg(uint8_t reg_addr, uint8_t data)
{
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_WRITE_STATUS_REG);
SPI_ReadWrite(SPI0, reg_addr);
SPI_ReadWrite(SPI0, data);
W25N01G_Deassert();
}
uint8_t W25N01G_ReadReg(uint8_t reg_addr)
{
W25N01G_Assert();
SPI_ReadWrite(SPI0, W25N_CMD_READ_STATUS_REG);
SPI_ReadWrite(SPI0, reg_addr);
uint8_t data = SPI_ReadWrite(SPI0, 0xFF);
W25N01G_Deassert();
return data;
}