FM25V01铁电存储器驱动移植

2019-04-13 13:39发布

最近在做毕设,为了兼容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 );