外部FLASH芯片MX25L25735F移植文件系统失败

2019-03-23 18:03发布

本帖最后由 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 */



此帖出自小平头技术问答
0条回答