|
楼主 |
发表于 2018-11-15 17:41:10
|
显示全部楼层
本帖最后由 taobaofarmer 于 2018-11-15 17:44 编辑
/*
********************************************************************************
* .忙状态寄存器的BUSY位(D0位,只读)在写动作(页写、扇区擦除、块擦除、芯片擦除、写
* .状态寄存器)期间有效(指示忙),其余状态非忙,此函数执行后一直等到非忙状态才退出
********************************************************************************
*/
void W25Q_CheckBusy(void)
{
vu8 i;
W25Q_Select();
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0x05;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
do
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0xff;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
}
while(SPI2->DR & 0x01);
}
W25Q_DeSelect();
}
void W25Q_WriteEnable(void)
{
vu8 i;
W25Q_Select();
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0x06;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
}
W25Q_DeSelect();
}
void W25Q_WriteDisable(void)
{
vu8 i;
W25Q_Select();
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0x04;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
}
W25Q_DeSelect();
}
//address - 24位地址
//pHead - 存储读出数据的头指针
//len - 读出数据长度
void W25Q_ReadData(u32 address, u8 *pHead, u16 len)
{
u16 i;
u8 add2, add1, add0;
add2 = (u8)(address>>16);
add1 = (u8)(address>>8);
add0 = (u8)(address);
W25Q_CheckBusy();
W25Q_Select();
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET); //1-送读命令03H
SPI2->DR = 0x03;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET); //2-送高字节地址
SPI2->DR = add2;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET); //3-送中字节地址
SPI2->DR = add1;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET); //4-送低字节地址
SPI2->DR = add0;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
for(i=0; i<len; i++)
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0xff;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
pHead = SPI2->DR;
}
}
W25Q_DeSelect();
}
//扇区(4K Bytes)擦除,该参数是扇区的绝对起始地址
void W25Q_SectorErase(u32 add)
{
vu8 i;
u8 add2,add1,add0;
add2 = (u8)(add>>16);
add1 = (u8)(add>>8);
add0 = (u8)(add);
W25Q_CheckBusy();
W25Q_WriteEnable();
W25Q_Select();
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0x20;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = add2;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = add1;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = add0;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
}
W25Q_DeSelect();
W25Q_WriteDisable();
}
//整片擦除
void W25Q_ChipErase(void)
{
vu8 id;
W25Q_CheckBusy();
W25Q_WriteEnable();
W25Q_Select();
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0xc7;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
id = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0xff;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
id = SPI2->DR;
}
W25Q_DeSelect();
W25Q_CheckBusy();
W25Q_WriteDisable();
}
//address - 24位地址
//pHead - 存储读出数据的头指针
//len - 读出数据长度
void W25Q_PageProgram(u32 address, u8 *pHead, u16 len)
{
u16 i;
vu8 j;
u8 add2, add1, add0;
add2 = (u8)(address>>16);
add1 = (u8)(address>>8);
add0 = (u8)(address);
W25Q_CheckBusy();
W25Q_WriteEnable();
W25Q_Select();
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0x02;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = add2;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = add1;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = add0;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
i = SPI2->DR;
for(i=0; i<len; i++)
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = pHead;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
j = SPI2->DR;
}
}
W25Q_DeSelect();
W25Q_WriteDisable();
}
//Winbond Serial Flash Manufacturer ID:EFH
u8 W25Q_ReadManufacturer(void)
{
vu8 id;
W25Q_CheckBusy();
W25Q_Select();
{
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0x9f;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
id = SPI2->DR;
while((SPI2->SR & SPI_I2S_FLAG_TXE) == RESET);
SPI2->DR = 0xff;
while((SPI2->SR & SPI_I2S_FLAG_RXNE) == RESET);
id = SPI2->DR;
}
W25Q_DeSelect();
return id;
}
//下面是移植代码,只有4个函数,我用的是W25Q128
void lfs_MyConfig(u32 sectors)
{
//cfg.context = NULL;
//block device operations
cfg.read = lfs_block_device_read;
cfg.prog = lfs_block_device_prog;
cfg.erase = lfs_block_device_erase;
cfg.sync = lfs_block_device_sync;
//block device configuration
cfg.read_size = 256;
cfg.prog_size = 256;
cfg.block_size = 4096;
cfg.block_count = sectors;
cfg.lookahead = 256;
cfg.read_buffer = lfs_read_buf;
cfg.prog_buffer = lfs_prog_buf;
cfg.lookahead_buffer = lfs_lookahead_buf;
cfg.file_buffer = lfs_file_buf;
}
int lfs_block_device_read(const struct lfs_config *lfsc,
lfs_block_t block,
lfs_off_t off,
void *buffer,
lfs_size_t size)
{
W25Q_ReadData((block*lfsc->block_size)+off, (uint8_t *)buffer, size);
return LFS_ERR_OK;
}
int lfs_block_device_prog(const struct lfs_config *lfsc,
lfs_block_t block,
lfs_off_t off,
const void *buffer,
lfs_size_t size)
{
W25Q_PageProgram((block*lfsc->block_size)+off, (uint8_t*)buffer, size);
return LFS_ERR_OK;
}
int lfs_block_device_erase(const struct lfs_config *lfsc, lfs_block_t block)
{
W25Q_SectorErase(block*lfsc->block_size);
return LFS_ERR_OK;
}
int lfs_block_device_sync(const struct lfs_config *lfsc)
{
return LFS_ERR_OK;
}
uTemp[0] = W25Q_ReadManufacturer();
W25Q_ChipErase();
lfs_MyConfig(4096);
err = lfs_mount(&lfs, &cfg);
// reformat if we can't mount the filesystem
// this should only happen on the first boot
if(err)
{
lfs_format(&lfs, &cfg);
lfs_mount(&lfs, &cfg);
}
lfs_file_open(&lfs, &file_SysParams, "/boot", LFS_O_RDWR | LFS_O_CREAT);
memset(uTemp, 0x77, 32);
lfs_file_write(&lfs, &file_SysParams, uTemp, 15);
memset(uTemp, 0x88, 32);
lfs_file_read(&lfs, &file_SysParams, uTemp, 16);
|
|