545 lines
12 KiB
C
545 lines
12 KiB
C
|
|
/*
|
|||
|
|
*********************************************************************************************************
|
|||
|
|
* IAR Development Kits
|
|||
|
|
* on the
|
|||
|
|
*
|
|||
|
|
* M451
|
|||
|
|
*
|
|||
|
|
* Filename : spi_flash.c
|
|||
|
|
* Version : V1.00
|
|||
|
|
* Programmer(s) : Qian Xianghong
|
|||
|
|
*********************************************************************************************************
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#include "includes.h"
|
|||
|
|
|
|||
|
|
// Ƭѡ
|
|||
|
|
#define SFLASH_CS_LOW() LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_4)
|
|||
|
|
#define SFLASH_CS_HIGH() LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_4)
|
|||
|
|
|
|||
|
|
// Flash<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
#define SFLASH_OP_WREN 0x06 // Write Enable
|
|||
|
|
#define SFLASH_OP_WRDI 0x04 // Write Disable
|
|||
|
|
#define SFLASH_OP_RDSR 0x05 // Read Status Register
|
|||
|
|
#define SFLASH_OP_WRSR 0x01 // Write Status Register
|
|||
|
|
#define SFLASH_OP_READ 0x03 // Read Memory
|
|||
|
|
#define SFLASH_OP_FSTRD 0x0B // Read Memory at Higher Speed
|
|||
|
|
#define SFLASH_OP_PP 0x02 // Page Program
|
|||
|
|
#define SFLASH_OP_DPD 0xB9 // Deep Power-down Mode
|
|||
|
|
#define SFLASH_OP_RDID 0x9F // JEDEC-ID Read
|
|||
|
|
#define SFLASH_OP_PE 0x81 // Erase 256 Bytes of Memory Array
|
|||
|
|
#define SFLASH_OP_SE 0x20 // Erase 4 KBytes of Memory Array
|
|||
|
|
#define SFLASH_OP_CE 0xC7 // Erase Full Array
|
|||
|
|
#define SFLASH_OP_ULBPR 0x98 // Global Block Protection Unlock
|
|||
|
|
|
|||
|
|
// Flash״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>SR)д<><D0B4><EFBFBD><EFBFBD>(WEL)<29><>־λ
|
|||
|
|
#define SFLASH_WEL_Pos 1
|
|||
|
|
#define SFLASH_WEL_Msk (0x01 << SFLASH_WEL_Pos)
|
|||
|
|
|
|||
|
|
// Flash״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>SR)Busy<73><79>־λ
|
|||
|
|
#define SFLASH_BUSY_Pos 0
|
|||
|
|
#define SFLASH_BUSY_Msk (0x01 << SFLASH_BUSY_Pos)
|
|||
|
|
|
|||
|
|
// дFlash<73><68><EFBFBD><EFBFBD>
|
|||
|
|
uint8_t SFlash_wtBuf[SFLASH_ERASE_SIZE];
|
|||
|
|
//uint8_t *SFlash_wtBuf; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD>ڴ<EFBFBD>
|
|||
|
|
|
|||
|
|
// <20><>Flashȫ<68>ֻ<EFBFBD><D6BB><EFBFBD>
|
|||
|
|
uint8_t SFlash_rdBuf[SFLASH_ERASE_SIZE];
|
|||
|
|
//uint8_t *SFlash_rdBuf; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD>ڴ<EFBFBD>
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ʽΪx16+x15+x2+1,LSB˳<42><CBB3>
|
|||
|
|
uint16_t do_crc_16(unsigned short crc_reg, uint8_t *message, int16_t len)
|
|||
|
|
{
|
|||
|
|
int16_t i, j;
|
|||
|
|
uint16_t current;
|
|||
|
|
|
|||
|
|
for (i = 0; i < len; i++)
|
|||
|
|
{
|
|||
|
|
current = message[i];
|
|||
|
|
for (j = 0; j < 8; j++)
|
|||
|
|
{
|
|||
|
|
if ((crc_reg ^ current) & 0x0001)
|
|||
|
|
crc_reg = (crc_reg >> 1) ^ 0xA001;
|
|||
|
|
else
|
|||
|
|
crc_reg >>= 1;
|
|||
|
|
current >>= 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return crc_reg;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SFlash_Init()
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SFlash_Open()
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD>ڴ<EFBFBD>
|
|||
|
|
// SFlash_rdBuf = SRAM_Alloc(SFLASH_ERASE_SIZE);
|
|||
|
|
// SFlash_wtBuf = SRAM_Alloc(SFLASH_ERASE_SIZE);
|
|||
|
|
|
|||
|
|
// LL_SPI_SetRxFIFOThreshold(SPI1, LL_SPI_RX_FIFO_TH_QUARTER);
|
|||
|
|
LL_SPI_Enable(SPI1);
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
SFlash_ReadID();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SFlash_ReadID()
|
|||
|
|
{
|
|||
|
|
uint8_t i;
|
|||
|
|
uint32_t priMask;
|
|||
|
|
|
|||
|
|
priMask = __get_PRIMASK();
|
|||
|
|
__disable_irq();
|
|||
|
|
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_RDID;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
PRINTF("\r\nFlash ID is: ");
|
|||
|
|
for(i = 0; i < 3; i++)
|
|||
|
|
{
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = 0; // <20>ṩCLK
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
PRINTF("%02X ", *(__IO uint8_t *)&SPI1->DR);
|
|||
|
|
}
|
|||
|
|
PRINTF("\r\n");
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
if(!priMask)
|
|||
|
|
__enable_irq();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t SFlash_UnlockBPR()
|
|||
|
|
{
|
|||
|
|
uint32_t priMask;
|
|||
|
|
|
|||
|
|
priMask = __get_PRIMASK();
|
|||
|
|
__disable_irq();
|
|||
|
|
|
|||
|
|
SFlash_WriteEN();
|
|||
|
|
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
// Write Enabled
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_ULBPR;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
if(!priMask)
|
|||
|
|
__enable_irq();
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t SFlash_WriteEN()
|
|||
|
|
{
|
|||
|
|
uint8_t SR = 0x00;
|
|||
|
|
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
// Write Enabled
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_WREN;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
// Read SR
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_RDSR;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = 0; // <20>ṩCLK
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
SR = *(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
// Check WEL
|
|||
|
|
if(SR & SFLASH_WEL_Msk)
|
|||
|
|
return 1;
|
|||
|
|
PRINTF("\r\nWrite enable failed\r\n");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint8_t SFlash_WriteDI()
|
|||
|
|
{
|
|||
|
|
uint8_t SR = 0xFF;
|
|||
|
|
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
// Write Enabled
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_WRDI;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
// Read SR
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_RDSR;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = 0; // <20>ṩCLK
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
SR = *(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
// Check WEL
|
|||
|
|
if(SR & SFLASH_WEL_Msk)
|
|||
|
|
{
|
|||
|
|
PRINTF("\r\nWrite disable failed\r\n");
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint32_t SFlash_BufferRead(uint32_t Addr, uint8_t *buf, uint32_t nbytes)
|
|||
|
|
{
|
|||
|
|
uint32_t i;
|
|||
|
|
uint32_t priMask;
|
|||
|
|
|
|||
|
|
priMask = __get_PRIMASK();
|
|||
|
|
__disable_irq();
|
|||
|
|
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
// Read
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_READ;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address highest byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = (Addr >> 16) & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address high byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = (Addr >> 8) & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address low byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = Addr & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// data
|
|||
|
|
for(i = 0; i < nbytes && Addr + i < SFLASH_SIZE; i++)
|
|||
|
|
{
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = 0; // <20>ṩCLK
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
buf[i] = *(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
if(!priMask)
|
|||
|
|
__enable_irq();
|
|||
|
|
|
|||
|
|
return i;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SFlash_PageErase(uint32_t Addr)
|
|||
|
|
{
|
|||
|
|
uint8_t SR = 0xFF;
|
|||
|
|
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
// Sector erase
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_PE;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address highest byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = (Addr >> 16) & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address high byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = (Addr >> 8) & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address low byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = Addr & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
// Read SR
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_RDSR;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = 0; // <20>ṩCLK
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
SR = *(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
} while(SR & SFLASH_BUSY_Msk);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SFlash_SectorErase(uint32_t Addr)
|
|||
|
|
{
|
|||
|
|
uint8_t SR = 0xFF;
|
|||
|
|
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
// Sector erase
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_SE;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address highest byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = (Addr >> 16) & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address high byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = (Addr >> 8) & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address low byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = Addr & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
// Read SR
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_RDSR;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = 0; // <20>ṩCLK
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
SR = *(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
} while(SR & SFLASH_BUSY_Msk);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SFlash_ChipErase()
|
|||
|
|
{
|
|||
|
|
uint8_t SR = 0xFF;
|
|||
|
|
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
// Chip erase
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_CE;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
// Read SR
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_RDSR;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = 0; // <20>ṩCLK
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
SR = *(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
} while(SR & SFLASH_BUSY_Msk);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint16_t SFlash_PageProgram(uint32_t Addr, uint8_t *buf)
|
|||
|
|
{
|
|||
|
|
uint8_t SR = 0xFF;
|
|||
|
|
uint16_t i;
|
|||
|
|
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
// Page grogram
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_PP;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address highest byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = (Addr >> 16) & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address high byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = (Addr >> 8) & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// address low byte
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = Addr & 0xFF;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
// data
|
|||
|
|
for(i = 0; i < SFLASH_PAGE_SIZE && Addr + i < SFLASH_SIZE; i++)
|
|||
|
|
{
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = buf[i];
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
|
|||
|
|
// Read SR
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
SFLASH_CS_LOW();
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = SFLASH_OP_RDSR;
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
*(__IO uint8_t *)&SPI1->DR = 0; // <20>ṩCLK
|
|||
|
|
while(!(SPI1->SR & SPI_SR_RXNE));
|
|||
|
|
SR = *(__IO uint8_t *)&SPI1->DR;
|
|||
|
|
|
|||
|
|
SFLASH_CS_HIGH();
|
|||
|
|
} while(SR & SFLASH_BUSY_Msk);
|
|||
|
|
|
|||
|
|
return i;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint16_t SFlash_SectorProgram(uint32_t Addr, uint8_t *buf)
|
|||
|
|
{
|
|||
|
|
uint16_t i = 0;
|
|||
|
|
uint16_t j;
|
|||
|
|
uint32_t priMask;
|
|||
|
|
|
|||
|
|
for(j = 0; j < SFLASH_ERASE_SIZE; j += SFLASH_PAGE_SIZE)
|
|||
|
|
{
|
|||
|
|
priMask = __get_PRIMASK();
|
|||
|
|
__disable_irq();
|
|||
|
|
SFlash_WriteEN();
|
|||
|
|
i += SFlash_PageProgram(Addr + j, buf + j);
|
|||
|
|
if(!priMask)
|
|||
|
|
__enable_irq();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return i;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint32_t SFlash_BufferWrite(uint32_t Addr, uint8_t *buf, uint32_t nbytes)
|
|||
|
|
{
|
|||
|
|
uint32_t count, offset;
|
|||
|
|
uint32_t priMask;
|
|||
|
|
static uint8_t FF[SFLASH_ERASE_SIZE];
|
|||
|
|
static uint8_t first = 1;
|
|||
|
|
|
|||
|
|
if(first)
|
|||
|
|
{
|
|||
|
|
first = 0;
|
|||
|
|
memset(FF, 0xFF, SFLASH_ERASE_SIZE);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while(nbytes > 0)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3>ƫ<EFBFBD>ƣ<EFBFBD>ֻ<EFBFBD>е<EFBFBD>һҳ<D2BB>п<EFBFBD><D0BF>ܷ<EFBFBD>0<EFBFBD><30>
|
|||
|
|
offset = Addr % SFLASH_ERASE_SIZE;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>һҳ<D2BB><D2B3>д<EFBFBD><D0B4><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|||
|
|
count = SFLASH_ERASE_SIZE - offset;
|
|||
|
|
if(count > nbytes)
|
|||
|
|
count = nbytes;
|
|||
|
|
|
|||
|
|
// ҳ<><D2B3><EFBFBD><EFBFBD>
|
|||
|
|
Addr -= offset;
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
SFlash_BufferRead(Addr, SFlash_wtBuf, SFLASH_ERASE_SIZE);
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD>д
|
|||
|
|
if(memcmp(SFlash_wtBuf + offset, buf, count) != 0)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΪȫFF<46><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
|
|||
|
|
if(memcmp(SFlash_wtBuf + offset, FF, count) != 0)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ
|
|||
|
|
priMask = __get_PRIMASK();
|
|||
|
|
__disable_irq();
|
|||
|
|
SFlash_WriteEN();
|
|||
|
|
SFlash_PageErase(Addr);
|
|||
|
|
if(!priMask)
|
|||
|
|
__enable_irq();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
memcpy(SFlash_wtBuf + offset, buf, count);
|
|||
|
|
|
|||
|
|
// д<>뱾ҳ<EBB1BE><D2B3><EFBFBD><EFBFBD>
|
|||
|
|
priMask = __get_PRIMASK();
|
|||
|
|
__disable_irq();
|
|||
|
|
SFlash_WriteEN();
|
|||
|
|
SFlash_PageProgram(Addr, SFlash_wtBuf);
|
|||
|
|
if(!priMask)
|
|||
|
|
__enable_irq();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ
|
|||
|
|
Addr += SFLASH_ERASE_SIZE;
|
|||
|
|
buf += count;
|
|||
|
|
nbytes -= count;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return TRUE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint32_t SFlash_BufferVerify(uint32_t Addr, uint8_t *buf, uint32_t nbytes)
|
|||
|
|
{
|
|||
|
|
uint32_t data_len;
|
|||
|
|
|
|||
|
|
while(nbytes > 0)
|
|||
|
|
{
|
|||
|
|
if(nbytes > SFLASH_ERASE_SIZE)
|
|||
|
|
data_len = SFLASH_ERASE_SIZE;
|
|||
|
|
else
|
|||
|
|
data_len = nbytes;
|
|||
|
|
|
|||
|
|
SFlash_BufferRead(Addr, SFlash_wtBuf, data_len);
|
|||
|
|
if(memcmp(SFlash_wtBuf, buf, data_len) != 0)
|
|||
|
|
return FALSE;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ
|
|||
|
|
Addr += data_len;
|
|||
|
|
buf += data_len;
|
|||
|
|
nbytes -= data_len;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return TRUE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint16_t do_sflash_crc(unsigned long base_addr, long len)
|
|||
|
|
{
|
|||
|
|
unsigned short crc = 0;
|
|||
|
|
unsigned short data_len;
|
|||
|
|
|
|||
|
|
while(len > 0)
|
|||
|
|
{
|
|||
|
|
if(len > SFLASH_ERASE_SIZE)
|
|||
|
|
data_len = SFLASH_ERASE_SIZE;
|
|||
|
|
else
|
|||
|
|
data_len = len;
|
|||
|
|
|
|||
|
|
SFlash_BufferRead(base_addr, SFlash_rdBuf, data_len);
|
|||
|
|
crc = do_crc_16(crc, SFlash_rdBuf, data_len);
|
|||
|
|
|
|||
|
|
base_addr += data_len;
|
|||
|
|
len -= data_len;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return crc;
|
|||
|
|
}
|