123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641 |
- #include "nor_flash.h"
- #include "interface.h"
- #include <inttypes.h>
- #define ADDR_SHIFT(A) (NOR_FLASH_ADDR + (2 * (A)))
- #define NOR_WRITE(Address, Data) (*(__IO uint16_t *)(Address) = (Data))
- #define BlockErase_Timeout ((uint32_t)0x00A00000)
- #define ChipErase_Timeout ((uint32_t)0x30000000)
- #define Program_Timeout ((uint32_t)0x00001400)
- #define NOR_IS_BUSY() (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) == RESET)
- static void NOR_QuitToReadStatus(void);
- static uint8_t NOR_GetStatus(uint32_t Timeout);
- void nor_flash_init(void)
- {
- FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
- FSMC_NORSRAMTimingInitTypeDef p;
-
-
- p.FSMC_AddressSetupTime = 0x06;
- p.FSMC_AddressHoldTime = 0x01;
- p.FSMC_DataSetupTime = 0x0C;
- p.FSMC_BusTurnAroundDuration = 0x00;
- p.FSMC_CLKDivision = 0x00;
- p.FSMC_DataLatency = 0x00;
- p.FSMC_AccessMode = FSMC_AccessMode_B;
- FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
- FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
- FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
- FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
- FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
- FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
- FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
- FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
- FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
- FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
- FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
- FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
- FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
- FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
- FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
- FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
-
- FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2, ENABLE);
- }
- uint32_t NOR_ReadID(void)
- {
- uint32_t uiID;
- uint8_t id1, id2, id3, id4;
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x0090);
- id1 = *(__IO uint16_t *)ADDR_SHIFT(0x0000);
- id2 = *(__IO uint16_t *)ADDR_SHIFT(0x0001);
- id3 = *(__IO uint16_t *)ADDR_SHIFT(0x000E);
- id4 = *(__IO uint16_t *)ADDR_SHIFT(0x000F);
- uiID = ((uint32_t)id1 << 24) | ((uint32_t)id2 << 16) | ((uint32_t)id3 << 8) | id4;
- NOR_WRITE(NOR_FLASH_ADDR, 0x00F0);
- return uiID;
- }
- static void NOR_QuitToReadStatus(void)
- {
- NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055);
- NOR_WRITE(NOR_FLASH_ADDR, 0x00F0);
- }
- static uint8_t NOR_GetStatus(uint32_t Timeout)
- {
- uint16_t val1 = 0x00;
- uint16_t val2 = 0x00;
- uint8_t status = NOR_ONGOING;
- uint32_t timeout = Timeout;
-
- while ((!NOR_IS_BUSY()) && (timeout > 0))
- {
- timeout--;
- }
-
- timeout = Timeout;
- while (NOR_IS_BUSY() && (timeout > 0))
- {
- timeout--;
- }
-
-
- while ((Timeout != 0x00) && (status != NOR_SUCCESS))
- {
- Timeout--;
-
- val1 = *(__IO uint16_t *)(NOR_FLASH_ADDR);
- val2 = *(__IO uint16_t *)(NOR_FLASH_ADDR);
-
- if ((val1 & 0x0040) == (val2 & 0x0040))
- {
- return NOR_SUCCESS;
- }
-
- if ((val1 & 0x0020) != 0x0020)
- {
- status = NOR_ONGOING;
- }
- val1 = *(__IO uint16_t *)(NOR_FLASH_ADDR);
- val2 = *(__IO uint16_t *)(NOR_FLASH_ADDR);
- if ((val1 & 0x0040) == (val2 & 0x0040))
- {
- return NOR_SUCCESS;
- }
- else if ((val1 & 0x0020) == 0x0020)
- {
- status = NOR_ERROR;
- NOR_QuitToReadStatus();
- }
- }
- if (Timeout == 0x00)
- {
- status = NOR_TIMEOUT;
- NOR_QuitToReadStatus();
- }
-
- return (status);
- }
- uint8_t NOR_EraseChip(void)
- {
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x0080);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x0010);
- return (NOR_GetStatus(ChipErase_Timeout));
- }
- void NOR_StartEraseChip(void)
- {
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x0080);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x0010);
- NOR_GetStatus(1000);
- }
- uint8_t NOR_CheckStatus(void)
- {
- uint16_t val1 = 0x00;
- uint16_t val2 = 0x00;
- uint8_t status = NOR_ONGOING;
- uint32_t timeout = 10;
-
-
- while ((timeout != 0x00) && (status != NOR_SUCCESS))
- {
- timeout--;
-
- val1 = *(__IO uint16_t *)(NOR_FLASH_ADDR);
- val2 = *(__IO uint16_t *)(NOR_FLASH_ADDR);
-
- if ((val1 & 0x0040) == (val2 & 0x0040))
- {
- return NOR_SUCCESS;
- }
-
- if ((val1 & 0x0020) != 0x0020)
- {
- status = NOR_ONGOING;
- }
- val1 = *(__IO uint16_t *)(NOR_FLASH_ADDR);
- val2 = *(__IO uint16_t *)(NOR_FLASH_ADDR);
- if ((val1 & 0x0040) == (val2 & 0x0040))
- {
- return NOR_SUCCESS;
- }
- else if ((val1 & 0x0020) == 0x0020)
- {
- status = NOR_ERROR;
- NOR_QuitToReadStatus();
- }
- }
- if (timeout == 0x00)
- {
- status = NOR_TIMEOUT;
-
- }
-
- return (status);
- }
- uint8_t NOR_EraseSector(uint32_t _uiBlockAddr)
- {
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x0080);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE((NOR_FLASH_ADDR + _uiBlockAddr), 0x30);
- return (NOR_GetStatus(BlockErase_Timeout));
- }
- uint8_t NOR_ReadByte(uint32_t _uiWriteAddr)
- {
- uint16_t usHalfWord;
- if (_uiWriteAddr % 2)
- {
- usHalfWord = *(uint16_t *)(NOR_FLASH_ADDR + _uiWriteAddr - 1);
- return (usHalfWord >> 8);
- }
- else
- {
- usHalfWord = *(uint16_t *)(NOR_FLASH_ADDR + _uiWriteAddr);
- return usHalfWord;
- }
- }
- void NOR_ReadBuffer(uint8_t *_pBuf, uint32_t _uiWriteAddr, uint32_t _uiBytes)
- {
- uint16_t usHalfWord;
- uint16_t *pNor16;
- uint32_t i;
- uint32_t uiNum;
- uiNum = _uiBytes;
-
- if (_uiWriteAddr % 2)
- {
- usHalfWord = *(uint16_t *)(NOR_FLASH_ADDR + _uiWriteAddr - 1);
- *_pBuf++ = (usHalfWord >> 8);
- uiNum--;
- _uiWriteAddr++;
- }
-
- pNor16 = (uint16_t *)(NOR_FLASH_ADDR + _uiWriteAddr);
- for (i = 0; i < uiNum / 2; i++)
- {
- usHalfWord = *pNor16++;
- *_pBuf++ = usHalfWord;
- *_pBuf++ = usHalfWord >> 8;
- uiNum -= 2;
- }
-
- if (uiNum == 1)
- {
- *_pBuf++ = *pNor16;
- }
- }
- uint8_t NOR_WriteHalfWord(uint32_t _uiWriteAddr, uint16_t _usData)
- {
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00A0);
- NOR_WRITE(NOR_FLASH_ADDR + _uiWriteAddr, _usData);
- return (NOR_GetStatus(Program_Timeout));
- }
- uint8_t NOR_WriteByte(uint32_t _uiWriteAddr, uint8_t _ucByte)
- {
- uint16_t usHalfWord;
- if (_uiWriteAddr % 2)
- {
-
- usHalfWord = *(uint16_t *)(NOR_FLASH_ADDR + _uiWriteAddr - 1);
- usHalfWord &= 0x00FF;
- usHalfWord |= (_ucByte << 8);
- }
- else
- {
-
- usHalfWord = *(uint16_t *)(NOR_FLASH_ADDR + _uiWriteAddr);
- usHalfWord &= 0xFF00;
- usHalfWord |= _ucByte;
- }
- return NOR_WriteHalfWord(_uiWriteAddr, usHalfWord);
- }
- uint8_t NOR_WriteInPage(uint16_t *pBuffer, uint32_t _uiWriteAddr, uint16_t _usNumHalfword)
- {
- uint32_t lastloadedaddress;
- uint32_t currentaddress;
- uint32_t endaddress;
-
- if (_usNumHalfword > 32)
- {
- return NOR_ERROR;
- }
- if ((_uiWriteAddr % 2) != 0)
- {
- return NOR_ERROR;
- }
- _uiWriteAddr = _uiWriteAddr / 2;
- currentaddress = _uiWriteAddr;
- endaddress = _uiWriteAddr + _usNumHalfword - 1;
- lastloadedaddress = _uiWriteAddr;
-
- NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
-
- NOR_WRITE(ADDR_SHIFT(_uiWriteAddr), 0x0025);
- NOR_WRITE(ADDR_SHIFT(_uiWriteAddr), (_usNumHalfword - 1));
-
- while (currentaddress <= endaddress)
- {
-
- lastloadedaddress = currentaddress;
- NOR_WRITE(ADDR_SHIFT(currentaddress), *pBuffer++);
- currentaddress += 1;
- }
- NOR_WRITE(ADDR_SHIFT(lastloadedaddress), 0x29);
- return (NOR_GetStatus(Program_Timeout));
- }
- uint8_t NOR_WriteBuffer(uint8_t *_pBuf, uint32_t _uiWriteAddr, uint32_t _uiBytes)
- {
- uint16_t usHalfWord;
- uint32_t i;
- uint32_t uiNum;
- uint8_t ucStatus;
- uiNum = _uiBytes;
-
- if (_uiWriteAddr % 2)
- {
-
- usHalfWord = *(uint16_t *)(NOR_FLASH_ADDR + _uiWriteAddr - 1);
- usHalfWord &= 0x00FF;
- usHalfWord |= ((*_pBuf++) << 8);
- ucStatus = NOR_WriteHalfWord(_uiWriteAddr - 1, usHalfWord);
- if (ucStatus != NOR_SUCCESS)
- {
- goto err_quit;
- }
- uiNum--;
- _uiWriteAddr++;
- }
-
- for (i = 0; i < uiNum / 2; i++)
- {
- usHalfWord = *_pBuf++;
- usHalfWord |= ((*_pBuf++) << 8);
- ucStatus = NOR_WriteHalfWord(_uiWriteAddr, usHalfWord);
- if (ucStatus != NOR_SUCCESS)
- {
- goto err_quit;
- }
- _uiWriteAddr += 2;
- }
-
- if (uiNum % 2)
- {
-
- usHalfWord = *(uint16_t *)(NOR_FLASH_ADDR + _uiWriteAddr);
- usHalfWord &= 0xFF00;
- usHalfWord |= (*_pBuf++);
- ucStatus = NOR_WriteHalfWord(_uiWriteAddr, usHalfWord);
- if (ucStatus != NOR_SUCCESS)
- {
- goto err_quit;
- }
- }
- ucStatus = NOR_SUCCESS;
- err_quit:
- return ucStatus;
- }
|