本帖最后由 qwerghf 于 2016-8-18 19:20 编辑
在stm32f207的芯片作为主控下,给MX25L25735F 移植文件系统,底层可以正常读取数据,但是就是无法创建,显示无文件系统,单步调试没有发现不对的地方。不知道大家碰过没有?希望知道的说一下,多谢。附上驱动。
//擦除一个扇区
//Dst_Addr:扇区地址 根据实际容量设置
//擦除一个山区的最少时间
void MX25XX_Erase_Sector(u32 eraseAddr)
{
uint8_t cmd = 0;
cmd = sFLASH_MX_4kB_SECTOR_ERASE;
eraseAddr &= sFLASH_4kB_SECTOR_ALIGN;
SpiFlashWriteEn();
sFLASH_CS_LOW();
SpiFlashSendByte(cmd);
SpiFlashSendByte((eraseAddr >> 24) & 0xFF);
SpiFlashSendByte((eraseAddr >> 16) & 0xFF);
SpiFlashSendByte((eraseAddr >> 8) & 0xFF);
SpiFlashSendByte(eraseAddr & 0xFF);
sFLASH_CS_HIGH();
SpiFlashWaitReady();
}
//读取SPI FLASH
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(32bit)
//NumByteToRead:要读取的字节数(最大65535)
void MX25XX_Read(u8* pBuffer,u32 ReadAddr,u16 NumByteToRead)
{
uint32_t i = 0;
sFLASH_CS_LOW();
SpiFlashSendByte((uint8_t)sFLASH_MX_READ_MEMORY_ARRAY);
SpiFlashSendByte((ReadAddr >> 24) & 0xFF);
SpiFlashSendByte((ReadAddr >> 16) & 0xFF);
SpiFlashSendByte((ReadAddr >> 8) & 0xFF);
SpiFlashSendByte(ReadAddr & 0xFF);
// 写数据
for (i = 0; i < NumByteToRead; i++)
{
while ((sFLASH_SPI->SR & SPI_I2S_FLAG_TXE) == (uint16_t)RESET);
// 数据发送
sFLASH_SPI->DR = sFLASH_DUMMY_BYTE;
// 等待数据接收
while ((sFLASH_SPI->SR & SPI_I2S_FLAG_RXNE) == (uint16_t)RESET);
// 数据接收
pBuffer
= sFLASH_SPI->DR;
}
sFLASH_CS_HIGH();
}
//SPI在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(32bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!
void MX25XX_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u16 i;
SpiFlashWriteEn();
sFLASH_CS_LOW();
SpiFlashSendByte(sFLASH_MX_PAGE_PROGRAM);
SpiFlashSendByte((WriteAddr >> 24) & 0xFF);
SpiFlashSendByte((WriteAddr >> 16) & 0xFF);
SpiFlashSendByte((WriteAddr >> 8) & 0xFF);
SpiFlashSendByte(WriteAddr & 0xFF);
for (i = 0; i < NumByteToWrite; i++)
{
SpiFlashSendByte(pBuffer);
}
sFLASH_CS_HIGH();
SpiFlashWaitReady();
}
//无检验写SPI FLASH
//必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
//具有自动换页功能
//在指定地址开始写入指定长度的数据,但是要确保地址不越界!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(32bit)
//NumByteToWrite:要写入的字节数(最大65535)
//CHECK OK
void MX25XX_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u16 pageremain;
pageremain = sFLASH_PAGE_SIZE - WriteAddr%sFLASH_PAGE_SIZE; //单页剩余的字节数
if(NumByteToWrite<=pageremain) pageremain = NumByteToWrite;//不大于256个字节
while(1)
{
MX25XX_Write_Page(pBuffer,WriteAddr,pageremain);
if(NumByteToWrite == pageremain) break;//写入结束了
else //NumByteToWrite>pageremain
{
pBuffer += pageremain;
WriteAddr += pageremain;
NumByteToWrite -= pageremain; //减去已经写入了的字节数
if(NumByteToWrite>256) pageremain = 256; //一次可以写入256个字节
else pageremain = NumByteToWrite; //不够256个字节了
}
};
}
//写SPI FLASH
//在指定地址开始写入指定长度的数据
//该函数带擦除操作!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(32bit)
//NumByteToWrite:要写入的字节数(最大65535)
u8 MX25XX_BUFFER[4096];
void MX25XX_Write(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
{
u32 secpos;
u16 secoff;
u16 secremain;
u16 i;
u8 * MX25XX_BUF;
MX25XX_BUF = MX25XX_BUFFER;
secpos = WriteAddr/4096;//扇区地址
secoff = WriteAddr%4096;//在扇区内的偏移
secremain = 4096-secoff;//扇区剩余空间大小
//printf("ad:%X,nb:%X
",WriteAddr,NumByteToWrite);//测试用
if(NumByteToWrite <= secremain) secremain = NumByteToWrite;//不大于4096个字节
while(1)
{
MX25XX_Read(MX25XX_BUF,secpos*4096,4096);//读出整个扇区的内容
for(i=0;i<secremain;i++)//校验数据
{
if(MX25XX_BUF[secoff+i] != 0XFF)break;//需要擦除
}
if(i<secremain)//需要擦除
{
MX25XX_Erase_Sector(secpos);//擦除这个扇区
for(i=0;i<secremain;i++) //复制
{
MX25XX_BUF[i+secoff] = pBuffer;
}
MX25XX_Write_NoCheck(MX25XX_BUF,secpos*4096,4096);//写入整个扇区
}else MX25XX_Write_NoCheck(pBuffer,WriteAddr,secremain);//写已经擦除了的,直接写入扇区剩余区间.
if(NumByteToWrite == secremain)break;//写入结束了
else//写入未结束
{
secpos++;//扇区地址增1
secoff=0;//偏移位置为0
pBuffer += secremain; //指针偏移
WriteAddr += secremain;//写地址偏移
NumByteToWrite -= secremain; //字节数递减
if(NumByteToWrite > 4096) secremain = 4096; //下一个扇区还是写不完
else secremain = NumByteToWrite; //下一个扇区可以写完了
}
};
}
#define USB_DISK 0 //U盘,卷标为0
#define EX_FLASH 1 //外部flash,卷标为1
#define FLASH_SECTOR_SIZE 512
//对于MX25L25735F
//前28M字节给fatfs用,28M字节后,给客户自己用
u16 FLASH_SECTOR_COUNT=2048*28; //MX25L25735F,前28M字节给FATFS占用
#define FLASH_BLOCK_SIZE 8 //每个BLOCK有8个扇区
static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */
extern USB_OTG_CORE_HANDLE USB_OTG_Core;
extern USBH_HOST USB_Host;
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE drv /* Physical drive number (0) */
)
{
u8 res=0;
switch(drv)
{
case USB_DISK://U盘
if(HCD_IsDeviceConnected(&USB_OTG_Core)) return 0;
else return 1;
case EX_FLASH://外部flash
SpiFlashInit();
FLASH_SECTOR_COUNT=2048*28;//MX25L25735F,前28M字节给FATFS占用
break;
default:
res=1;
}
if(res)return STA_NOINIT;
else return 0; //初始化成功
}
/*-----------------------------------------------------------------------*/
/* Get Disk Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE drv /* Physical drive number (0) */
)
{
return 0;
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE drv, /* Physical drive number (0) */
BYTE *buff, /* Pointer to the data buffer to store read data */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
u8 res=0;
if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
switch(drv)
{
case USB_DISK://U盘
if(HCD_IsDeviceConnected(&USB_OTG_Core))
{
do
{
res = USBH_MSC_Read10(&USB_OTG_Core, buff,sector,512);
USBH_MSC_HandleBOTXfer(&USB_OTG_Core ,&USB_Host);
if(!HCD_IsDeviceConnected(&USB_OTG_Core))
{
return RES_ERROR;
}
}
while(res == USBH_MSC_BUSY );
}
if(res == USBH_MSC_OK) return RES_OK;
return RES_ERROR;
case EX_FLASH://外部flash
for(; count>0; count--)
{
MX25XX_Read(buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff += FLASH_SECTOR_SIZE;
}
res=0;
break;
default:
res=1;
}
if(res==0x00)return RES_OK;
else return RES_ERROR;
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive number (0) */
const BYTE *buff, /* Pointer to the data to be written */
DWORD sector, /* Start sector number (LBA) */
BYTE count /* Sector count (1..255) */
)
{
u8 res=0;
if (!count)return RES_PARERR;//count不能等于0,否则返回参数错误
switch(drv)
{
case USB_DISK://U盘
if(HCD_IsDeviceConnected(&USB_OTG_Core))
{
do
{
res = USBH_MSC_Write10(&USB_OTG_Core,(BYTE*)buff,sector,512);
USBH_MSC_HandleBOTXfer(&USB_OTG_Core, &USB_Host);
if(!HCD_IsDeviceConnected(&USB_OTG_Core))
{
return RES_ERROR;
}
}
while(res == USBH_MSC_BUSY );
}
if(res == USBH_MSC_OK) return RES_OK;
return RES_ERROR;
case EX_FLASH://外部flash
for(; count>0; count--)
{
MX25XX_Write((u8*)buff,sector*FLASH_SECTOR_SIZE,FLASH_SECTOR_SIZE);
sector++;
buff += FLASH_SECTOR_SIZE;
}
res=0;
break;
default:
res=1;
}
if(res == 0x00)return RES_OK;
else return RES_ERROR;
}
#endif /* _READONLY == 0 */
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
#if _USE_IOCTL != 0
DRESULT disk_ioctl (
BYTE drv, /* Physical drive number (0) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
if(drv == USB_DISK)//U盘
{
switch(ctrl)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(DWORD*)buff = 512;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = 512;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = (DWORD)USBH_MSC_Param.MSCapacity;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
}
else if(drv == EX_FLASH) //外部FLASH
{
switch(ctrl)
{
case CTRL_SYNC:
res = RES_OK;
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = FLASH_SECTOR_SIZE;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = FLASH_BLOCK_SIZE;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = FLASH_SECTOR_COUNT;
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
} else res=RES_ERROR;//其他的不支持
return res;
}
#endif /* _USE_IOCTL != 0 */
此帖出自
小平头技术问答
一周热门 更多>