/********************************************************************** 45DB011 Max 20MHz clock, using 8 MHz click, 512 Pages (264 Bytes/Page) MX25l8006EM2C 台湾旺宏 8M字节 86/66/33MHZ 页256Byte 最大5ms 10万次擦写 **********************************************************************/ //#include "stm32f10x_lib.h" #include "SPI_Flash.h" #include "Flash.h" #define FLASH_PAGE_SIZE 256 __no_init unsigned char spi_buf[FLASH_PAGE_SIZE]@0x20004000;//[256];; //__no_init SPI_InitTypeDef SPI_InitStructure@0x20006000;//[256];; //__no_init GPIO_InitTypeDef GPIO_InitStructure@0x20006100;//[256];; //unsigned int Update_Len; //unsigned int page; //unsigned char* Update_Ptr; //unsigned char Update_Data; unsigned char m_ucFlashBuf[FLASH_PAGE_SIZE]={0}; //unsigned char m_ucFlashBuf[FLASH_PAGE_SIZE]; extern u16 FlashDataRAM[]; //0XC2 0X13 void FlashReadID(u8 *Data)@ "FLASHCODE" { u8 i; Select_Flash(); SPI_Flash_SendByte(0x90); SPI_Flash_SendByte(0x00); SPI_Flash_SendByte(0x00); SPI_Flash_SendByte(0x00); for(i = 0; i < 2; i++) { Data[i] = SPI_Flash_ReadByte(); } NotSelect_Flash(); } /******************************************************************************* * Function Name : SPI_FLASH_Init * Description : Initializes the peripherals used by the SPI FLASH driver. * Input : None * Output : None * Return : None *******************************************************************************/ void SPI_Flash_Init(void)@ "FLASHCODE" { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable SPI1 GPIOA and GPIOB clocks */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE); /* Configure SPI1 pins: NSS, SCK, MISO and MOSI */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14| GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Deselect the FLASH: Chip Select high */ NotSelect_Flash(); /* SPI1 configuration */ 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_4; //divied by 2, SPI clock is (32M/2)/2=8MHz //SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; // 4m SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure); /* Enable SPI1 */ SPI_Cmd(SPI2, ENABLE); //flash_write_enable(); } /******************************************************************************* * Function Name : SPI_FLASH_ReadByte * Description : Reads a byte from the SPI Flash. * This function must be used only if the Start_Read_Sequence * function has been previously called. * Input : None * Output : None * Return : Byte Read from the SPI Flash. *******************************************************************************/ //u8 SPI_Flash_ReadByte(void)@ "FLASHCODE" //{ // return (SPI_Flash_SendByte(Dummy_Byte)); //} unsigned char SPI_Flash_ReadByte(void)@ "FLASHCODE" { return (SPI_Flash_SendByte(Dummy_Byte)); } /******************************************************************************* * Function Name : SPI_FLASH_SendByte * Description : Sends a byte through the SPI interface and return the byte * received from the SPI bus. * Input : byte : byte to send. * Output : None * Return : The value of the received byte. *******************************************************************************/ u8 SPI_Flash_SendByte(u8 byte)@ "FLASHCODE" { /* Loop while DR register in not emplty */ while(SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET); /* Send byte through the SPI1 peripheral */ SPI_SendData(SPI2, byte); /* Wait to receive a byte */ while(SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET); /* Return the byte read from the SPI bus */ return SPI_ReceiveData(SPI2); } /* void FlashPageEarse(u16 page)@ "FLASHCODE" { FlashWaitBusy(); Select_Flash(); SPI_Flash_SendByte(PAGE_ERASE); SPI_Flash_SendByte((u8)(page >> 6)); SPI_Flash_SendByte((u8)(page << 2)); SPI_Flash_SendByte(Dummy_Byte); //|-23-|-22-|21|20|19|18|17|16|15|14|13|12|11|10|9|8|7|6|5|4|3|2|1|0| //|2个无关位|------------12位页地址-------------|----10个无关位-----| NotSelect_Flash(); } */ void Delay_100us_1(void) { unsigned int j; for(j=0; j<424; j++) { _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); } } void FlashPageRead(unsigned int wPage,unsigned char *Update_Ptr)@ "FLASHCODE" { unsigned short i=0; unsigned int uiAddr=0; //256 8006E --> 4096 page uiAddr = (unsigned int)(wPage*256); FlashWaitBusy(); Select_Flash(); SPI_Flash_SendByte(0x03); SPI_Flash_SendByte( (u8)((uiAddr>>16)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr>>8)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr)&0xFF) ); for (i = 0;i < 256; i++) { *Update_Ptr++=SPI_Flash_ReadByte(); } NotSelect_Flash(); } void flash_write_enable(void) { unsigned char state_reg=0x00; while((state_reg&0x02) == 0x00) { Select_Flash(); SPI_Flash_SendByte(0x06); NotSelect_Flash(); Delay_100us_1(); Select_Flash(); SPI_Flash_SendByte(FLASH_STATUS); state_reg=SPI_Flash_ReadByte(); NotSelect_Flash(); if( (state_reg&0x02) == 0x01 ) { break; } Delay_100us_1(); } } void FlashWaitBusy(void)@ "FLASHCODE" { unsigned char state_reg=0x00; while( 1 ) { Select_Flash(); SPI_Flash_SendByte(0x05); state_reg=SPI_Flash_ReadByte(); NotSelect_Flash(); //ClearWatchdog(); { //WDI_10; //IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //IWDG_ReloadCounter(); } if( (state_reg&0x01) == 0x00) { break; } } } void UClearWatchdog(void)@ "FLASHCODE" { unsigned char k; // P6DIR_bit.P6DIR_1 = 1; // P6OUT_bit.P6OUT_1 = 1; WDI_1; for (k=0;k<200;k++)//0 { _NOP(); } WDI_0; // P6OUT_bit.P6OUT_1 = 0; // WDTCTL = WDTPW + WDTSSEL + WDTCNTCL; //enable and clear watchdog, 2006-11-21 IWDG_ReloadCounter(); } //read flash data within page void D_spiReadFlashPage(unsigned int iadr,unsigned short ilen,unsigned char *pdin_data)//@ "FLASHCODE" { unsigned int i,tn; tn=ilen+(iadr%FLASH_PAGE_SIZE); FlashPageRead(iadr/FLASH_PAGE_SIZE,&spi_buf[0]); for(i=(iadr%FLASH_PAGE_SIZE);iFLASH_PAGE_SIZE) { FlashPageRead(page,&spi_buf[0]); for(i=0;iFLASH_PAGE_SIZE) { for(i=0;i 4096 page void flash_page_write(u16 wPage,u8 *Data) { unsigned short i=0; unsigned int uiAddr=0; uiAddr = (unsigned int)(wPage*256); FlashWaitBusy(); flash_write_enable(); Select_Flash(); SPI_Flash_SendByte(0x02); SPI_Flash_SendByte( (u8)((uiAddr>>16)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr>>8)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr)&0xFF) ); for (i = 0;i < 256; i++) { SPI_Flash_SendByte(Data[i]); } NotSelect_Flash(); } //256 8006E --> 4096 page void flash_page_read(unsigned short wPage, unsigned char* pData) { unsigned short i=0; unsigned int uiAddr=0; uiAddr = (unsigned int)(wPage*256); FlashWaitBusy(); Select_Flash(); SPI_Flash_SendByte(0x03); SPI_Flash_SendByte( (u8)((uiAddr>>16)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr>>8)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr)&0xFF) ); for (i = 0;i < 256; i++) { pData[i]=SPI_Flash_ReadByte(); } NotSelect_Flash(); } void flash_sector_erase(unsigned int uiAddr) { FlashWaitBusy(); flash_write_enable(); Select_Flash(); SPI_Flash_SendByte(0x20); SPI_Flash_SendByte( (u8)((uiAddr>>16)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr>>8)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr)&0xFF) ); NotSelect_Flash(); } void flash_sector_write(unsigned int uiAddr, unsigned short wLen) { unsigned short i=0; unsigned short wPage=0; unsigned char* m_flash_sector=0; m_flash_sector=(unsigned char*)FlashDataRAM; wPage = (unsigned short)(uiAddr/256); for( i=0; i<16; i++ ) { memcpy( &m_ucFlashBuf[0], &m_flash_sector[ 256*i ], 256 ); flash_page_write( wPage, &m_ucFlashBuf[0] ); wPage++; } SPI_Flash_SendByte(0x04); //dis write } void flash_fast_read( unsigned int uiAddr, unsigned short wLen ) { unsigned short i=0; unsigned char* m_flash_sector=0; m_flash_sector=(unsigned char*)FlashDataRAM; if(wLen>4096) { return; } FlashWaitBusy(); Select_Flash(); SPI_Flash_SendByte(0x0B); SPI_Flash_SendByte( (u8)((uiAddr>>16)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr>>8)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr)&0xFF) ); SPI_Flash_SendByte( 0x00 ); for (i = 0;i < wLen; i++) { m_flash_sector[i]=SPI_Flash_ReadByte(); } NotSelect_Flash(); } void FlashWaidBusy(void)@ "FLASHCODE" { unsigned char state_reg=0x00; while( 1 ) { Select_Flash(); SPI_Flash_SendByte(0x05); state_reg=SPI_Flash_ReadByte(); NotSelect_Flash(); UClearWatchdog(); if( (state_reg&0x01) == 0x00) { break; } } } void Flash_Page_Read(unsigned int wPage,unsigned char *Update_Ptr)@ "FLASHCODE" { unsigned short i=0; unsigned int uiAddr=0; //256 8006E --> 4096 page uiAddr = (unsigned int)(wPage*256); FlashWaidBusy(); Select_Flash(); SPI_Flash_SendByte(0x03); SPI_Flash_SendByte( (u8)((uiAddr>>16)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr>>8)&0xFF) ); SPI_Flash_SendByte( (u8)((uiAddr)&0xFF) ); for (i = 0;i < 256; i++) { *Update_Ptr++=SPI_Flash_ReadByte(); } NotSelect_Flash(); } /** * @brief Write block of data to the SPI FLASH. * @param WriteAddr: FLASH's internal address to write to. * @param pBuffer: pointer to the buffer containing the data to be written to the FLASH. * @param length: number of bytes to write to the FLASH. * @retval None. */ void hal_sFLASH_WriteData(u32 WriteAddr, u8 *pBuffer, u16 length) { u16 pageLength = 0; while (length > 0) { if ((WriteAddr & sFLASH_PAGE_MASK) == ((WriteAddr + length) & sFLASH_PAGE_MASK)) { pageLength = length; } else { pageLength = ((WriteAddr + sFLASH_PAGE_SIZE) & sFLASH_PAGE_MASK) - WriteAddr; } FlashWaitBusy(); flash_write_enable(); Select_Flash(); SPI_Flash_SendByte(0x02); SPI_Flash_SendByte((u8)((WriteAddr >> 16) & 0xFF)); SPI_Flash_SendByte((u8)((WriteAddr >> 8) & 0xFF)); SPI_Flash_SendByte((u8)((WriteAddr) & 0xFF)); for (u16 i = 0; i < pageLength; i++) { SPI_Flash_SendByte(pBuffer[i]); } NotSelect_Flash(); WriteAddr += pageLength; pBuffer += pageLength; length -= pageLength; } } /** * @brief Read block of data to the SPI FLASH. * @param ReadAddr: FLASH's internal address to read from. * @param pBuffer: pointer to the buffer containing the data to be read from the FLASH. * @param length: number of bytes to read from the FLASH. * @retval None. */ void hal_sFLASH_ReadData(u32 ReadAddr, u8 *pBuffer, u16 length) { FlashWaitBusy(); flash_write_enable(); Select_Flash(); SPI_Flash_SendByte(0x03); SPI_Flash_SendByte((u8)((ReadAddr >> 16) & 0xFF)); SPI_Flash_SendByte((u8)((ReadAddr >> 8) & 0xFF)); SPI_Flash_SendByte((u8)((ReadAddr) & 0xFF)); for (u16 i = 0; i < length; i++) { pBuffer[i] = SPI_Flash_SendByte(Dummy_Byte); } NotSelect_Flash(); }