FM25V01鐵電存儲器驅動移植

最近在做畢設,爲了兼容PIX的固件,硬件選用了PIX的FMUV5傳感器組合:
ICM20689
IST8310
MS5611
主控是STM32F407
其他的驅動都好移植 ICM20689 SPI讀取 使用42M速度時會出錯 改成4分頻到21M後正常每1MS讀取一次沒問題
但是移植到FM25V01時出現了卡頓 和普通的W25QXX不一樣,這個芯片在寫數據前不需要擦除,儘管寫,高達10^14次方讀寫壽命

FM25V01硬件原理圖:

在這裏插入圖片描述
驅動程序:

#include "Drv_fm25v01.h"
#include "stdio.h"

#define DUMMY_BYTE     0xFF


flash_info_t flash_info;
jedec_id_t flash_id;
static uint8_t Flash_SendByte ( uint8_t byte );
static uint8_t Flash_ReadID ( jedec_id_t *id );
static void Flash_WriteEnable ( void );
//static void Flash_WriteDisable ( void );
void Flash_Init( void )
{

    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef  SPI_InitStructure;

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    //SPI GPIO Configuration
    GPIO_PinAFConfig ( GPIOB, GPIO_PinSource13, GPIO_AF_SPI2 );
    GPIO_PinAFConfig ( GPIOB, GPIO_PinSource14, GPIO_AF_SPI2 );
    GPIO_PinAFConfig ( GPIOB, GPIO_PinSource15, GPIO_AF_SPI2 );

    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14| GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
    GPIO_Init ( GPIOB, &GPIO_InitStructure );

    //flash SPI CS
    GPIO_InitStructure.GPIO_Pin             = GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode            = GPIO_Mode_OUT ;   //推輓輸出
    GPIO_InitStructure.GPIO_OType           = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd            = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Speed           = GPIO_Speed_2MHz;
    GPIO_Init ( GPIOB, &GPIO_InitStructure );

    //SPI configuration
    SPI_I2S_DeInit ( SPI2 );
    SPI_InitStructure.SPI_Direction         = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode              = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize          = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL              = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA              = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS               = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//42/4=22
    SPI_InitStructure.SPI_FirstBit          = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial     = 7;
    SPI_Init ( SPI2, &SPI_InitStructure );
    SPI_Cmd ( SPI2, ENABLE );
    FM25VXX_CS_HIGH();

    /* Select the FLASH: Chip Select low */
    FM25VXX_CS_LOW();
    /* Send "0xff " instruction */
    Flash_SendByte ( DUMMY_BYTE );

    FM25VXX_CS_HIGH();

    /* read flash id */
    Flash_ReadID ( &flash_id );


    flash_info.initialized = 1;
}


static uint8_t Flash_SendByte ( uint8_t byte )
{
	
	while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET){}
    SPI_I2S_SendData(SPI2, byte);
    while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET){}
    return SPI_I2S_ReceiveData(SPI2);

}

u8 FM25V01_RDSR(void)//寄存器配置內容讀取
{
	u8 Reg_Status;

	FM25VXX_CS_LOW();
	Flash_SendByte(RDSR);
	Reg_Status = Flash_SendByte(0x00);
	FM25VXX_CS_HIGH();
	return(Reg_Status);
}
static void Flash_WriteEnable ( void )
{
    /* Select the FLASH: Chip Select low */
    FM25VXX_CS_LOW();
    /* Send Write Enable instruction */
    Flash_SendByte ( WREN );
    /* Deselect the FLASH: Chip Select high */
    FM25VXX_CS_HIGH();
}

uint8_t Flash_ReadID ( jedec_id_t *id )
{
    uint8_t *recv_buffer = ( uint8_t* ) id;

    /* Select the FLASH: Chip Select low */
    FM25VXX_CS_LOW();

    /* Send "RDID " instruction */
    Flash_SendByte ( RDID );

    /* Read a byte from the FLASH */
    *recv_buffer++ = Flash_SendByte ( DUMMY_BYTE );

    /* Read a byte from the FLASH */
    *recv_buffer++ = Flash_SendByte ( DUMMY_BYTE );

    /* Read a byte from the FLASH */
    *recv_buffer++ = Flash_SendByte ( DUMMY_BYTE );

    /* Deselect the FLASH: Chip Select high */
    FM25VXX_CS_HIGH();

    return id->Manufacturer;
}
/**
  * @brief  Reads a block of data from the FLASH.
  * @param buffer : pointer to the buffer that receives the data read
  *                  from the FLASH.
  * @param address : FLASH's internal address to read from.
  * @param lenght : number of bytes to read from the FLASH.
  * @retval : None
  */
void Flash_PageRead ( uint32_t address, uint8_t* buffer,  uint32_t lenght )
{

    
	/* Select the FLASH: Chip Select low */
    FM25VXX_CS_LOW();
    /* Send "Read from Memory " instruction */
    Flash_SendByte ( READ );

    /* Send ReadAddr high nibble address byte to read from */
    Flash_SendByte ( ( address & 0xFF0000 ) >> 16 );
    /* Send ReadAddr medium nibble address byte to read from */
    Flash_SendByte ( ( address & 0xFF00 ) >> 8 );
    /* Send ReadAddr low nibble address byte to read from */
    Flash_SendByte ( address & 0xFF );
	
    while ( lenght-- ) /* while there is data to be read */
    {
        /* Read a byte from the FLASH */
        *buffer++ = Flash_SendByte ( DUMMY_BYTE );
        /* Point to the next location where the byte read will be saved */
        
    }

    /* Deselect the FLASH: Chip Select high */
    FM25VXX_CS_HIGH();

}
/**
  * @brief  Writes more than one byte to the FLASH with a single WRITE
  *         cycle(Page WRITE sequence). The number of byte can't exceed
  *         the FLASH page size.
  * @param pBuffer : pointer to the buffer  containing the data to be
  *                  written to the FLASH.
  * @param WriteAddr : FLASH's internal address to write to.
  * @param NumByteToWrite : number of bytes to write to the FLASH,
  *                       must be equal or less than "SPI_FLASH_PageSize" value.
  * @retval : None
  */
void Flash_PageWrite ( uint32_t address, uint8_t* buffer,  uint32_t lenght )
{
	/* Select the FLASH: Chip Select low */
	FM25VXX_CS_LOW();
	
    Flash_WriteEnable();
    /* Select the FLASH: Chip Select low */
    FM25VXX_CS_HIGH();
	Delay_us(2);
	/* Select the FLASH: Chip Select low */
	FM25VXX_CS_LOW();
    /* Send "Write to Memory " instruction */
    Flash_SendByte ( WRITE );
    /* Send WriteAddr high nibble address byte to write to */
    Flash_SendByte ( ( address & 0xFF0000 ) >> 16 );
    /* Send WriteAddr medium nibble address byte to write to */
    Flash_SendByte ( ( address & 0xFF00 ) >> 8 );
    /* Send WriteAddr low nibble address byte to write to */
    Flash_SendByte ( address & 0xFF );

    /* while there is data to be written on the FLASH */
    while ( lenght-- )
    {
        /* Send the current byte */
        Flash_SendByte ( *buffer++ );
        /* Point on the next byte to be written */
        //buffer;
    }

    /* Deselect the FLASH: Chip Select high */
    FM25VXX_CS_HIGH();
	
	while (0x01 == (FM25V01_RDSR() & 0x01)); 
	
	Flash_SendByte(WRDI);         
	
}


flash_info_t *Flash_GetInfo ( void )
{
    return &flash_info;
}

頭文件:

#ifndef  _FM25V01_H
#define  _FM25V01_H

#include "stm32f4xx.h"
#include "include.h"

#define BANK0   0x00000
#define BANK1   0x20000
#define BANK2   0x30000
#define BANK01	0x01000
#define BANK02	0x00200
#define BANK03	0x00030

// FM25H20 Control Command
#define		WREN			0x06						// Set Write Enable Latch
#define		WRDI			0x04						// Write Disable
#define		RDSR			0x05						// Read Status Register
#define		WRSR			0x01						// Write Status Register 
#define		READ			0x03						// Read Memory Data.
#define 	FSTRD			0x0B						// Fast Read Memory Data.
#define		WRITE			0x02 						// Write Memory Data
#define		SLEEP			0xB9						// Enter Sleep Mode.
#define		RDID			0x9F						// Read Device ID.
#define 	SNR				0xC3						// Read S/N.

#define FM25VXX_CS_LOW()      GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET)
#define FM25VXX_CS_HIGH()     GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET)

typedef struct
{
    u8 initialized;
    u16 sector_size;
    u16 sector_count;
    u32 capacity;
} flash_info_t;
typedef struct
{
    uint8_t Manufacturer;             /* Manufacturer ID */
    uint8_t Memory;               /* Density Code */
    uint8_t Capacity;                /* Family Code */
    uint8_t rev;

} jedec_id_t;
/* ========================= FUNCTION PROTOTYPES =========================== */

// private
void Flash_Init( void );
void Flash_SectorErase(uint32_t address,uint8_t state);
void Flash_PageRead(uint32_t address,uint8_t* buffer,  uint32_t lenght);
void Flash_PageWrite(uint32_t address,uint8_t* buffer,  uint32_t lenght);

extern jedec_id_t flash_id;
extern flash_info_t flash_info;
#endif

讀寫的時候只需要對應BANK直接讀和寫即可:

Flash_PageWrite ( BANK0, &Parame[0], 255 );
Flash_PageRead ( BANK0, &Parame[0], 255 );
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章