| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- /*
- * Copyright (c) 2022 OpenLuat & AirM2M
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- #include "bl_inc.h"
- #ifdef __RUN_IN_RAM__
- #define __disable_irq()
- #define __disable_fault_irq()
- #define __enable_fault_irq()
- #define __enable_irq()
- #endif
- void __FUNC_IN_RAM__ CACHE_EncryptInit(uint8_t *key, uint8_t *iv, uint32_t start, uint32_t end)
- {
- int i;
- uint32_t ckey[4];
- uint32_t civ[4];
- for(i = 0; i < 4; i++)
- {
- ckey[3 - i] = BytesGetBe32(key + i * 4);
- civ[3 - i] = BytesGetBe32(iv + i * 4);
- }
- __disable_irq();
- for (i = 0; i < 5000; i++)
- {
- if (CACHE->CACHE_CS & CACHE_IS_BUSY) //cache正在从Flash中取指
- {
- continue;
- }
- break;
- }
- CACHE->CACHE_CS = 0x00000000 + CACHE_KEY_GEN; //密钥生成模式
- CACHE->CACHE_I3 = civ[3];
- CACHE->CACHE_I2 = civ[2];
- CACHE->CACHE_I1 = civ[1];
- CACHE->CACHE_I0 = civ[0];
- CACHE->CACHE_K3 = ckey[3];
- CACHE->CACHE_K2 = ckey[2];
- CACHE->CACHE_K1 = ckey[1];
- CACHE->CACHE_K0 = ckey[0];
- CACHE->CACHE_CS |= CACHE_KEY_GEN_START;
- for (i = 0; i < 10000; i++)
- {
- if((CACHE->CACHE_CS & CACHE_KEY_GEN_START) == 0)
- {
- break;
- }
- }
- CACHE->CACHE_CS = 0;
- CACHE->CACHE_SADDR = start;
- CACHE->CACHE_EADDR = end;
- CACHE->CACHE_CONFIG = 0xA5A50055;
- __enable_irq();
- }
- void __FUNC_IN_RAM__ CACHE_CleanAll(CACHE_TypeDef *Cache)
- {
- while (Cache->CACHE_CS & CACHE_IS_BUSY);
- Cache->CACHE_REF = CACHE_REFRESH_ALLTAG;
- Cache->CACHE_REF |= CACHE_REFRESH;
- while ((Cache->CACHE_REF & CACHE_REFRESH));
- }
- #ifdef __RUN_IN_RAM__
- typedef struct
- {
- uint8_t Instruction;
- QSPI_BusModeTypeDef BusMode;
- QSPI_CmdFormatTypeDef CmdFormat;
- uint32_t Address;
- uint32_t WrData;
- uint32_t RdData;
- }FLASH_CommandTypeDef;
- #define QSPI_FIFO_NUM 32
- #define FLASH_QSPI_TIMEOUT_DEFAULT_CNT (19000) //18944
- #define FLASH_QSPI_ACCESS_REQ_ENABLE (0x00000001U)
- #define FLASH_QSPI_FLASH_READY_ENABLE (0x0000006BU)
- static int32_t prvQSPI_Command(FLASH_CommandTypeDef *cmd, int32_t timeout)
- {
- int32_t i;
- int32_t status = -ERROR_OPERATION_FAILED;
- QSPI->REG_WDATA = cmd->WrData;
- QSPI->ADDRES = (QSPI->ADDRES & ~QUADSPI_ADDRESS_ADR) | (cmd->Address << 8);
- QSPI->FCU_CMD = (QSPI->FCU_CMD & ~(QUADSPI_FCU_CMD_CODE | QUADSPI_FCU_CMD_BUS_MODE | QUADSPI_FCU_CMD_CMD_FORMAT | QUADSPI_FCU_CMD_ACCESS_REQ)) | ((cmd->Instruction << 24) |((uint32_t)( cmd->BusMode<< 8)) |((uint32_t)( cmd->CmdFormat << 4))| (FLASH_QSPI_ACCESS_REQ_ENABLE));
- //Wait For CMD done
- for (i = 0; i < timeout; i += 4)
- {
- if (QSPI->INT_RAWSTATUS & QUADSPI_INT_RAWSTATUS_DONE_IR)
- {
- QSPI->INT_CLEAR = QUADSPI_INT_CLEAR_DONE;
- status = ERROR_NONE;
- break;
- }
- }
- cmd->RdData = QSPI->REG_RDATA;
- return status;
- }
- static int32_t prvQSPI_WriteEnable(QSPI_BusModeTypeDef bus_mode)
- {
- FLASH_CommandTypeDef sCommand;
- sCommand.Instruction = SPIFLASH_CMD_WREN;
- sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8;
- if (QSPI_BUSMODE_444 == bus_mode)
- {
- sCommand.BusMode = QSPI_BUSMODE_444;
- }
- else
- {
- sCommand.BusMode = QSPI_BUSMODE_111;
- }
- if (prvQSPI_Command(&sCommand, FLASH_QSPI_TIMEOUT_DEFAULT_CNT))
- {
- return -ERROR_OPERATION_FAILED;
- }
- return ERROR_NONE;
- }
- //PP,QPP,Sector Erase,Block Erase, Chip Erase, Write Status Reg, Erase Security Reg
- int32_t prvQSPI_IsBusy(QSPI_BusModeTypeDef bus_mode)
- {
- FLASH_CommandTypeDef sCommand;
- sCommand.Instruction = SPIFLASH_CMD_RDSR;
- sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_RREG8;
- if (QSPI_BUSMODE_444 == bus_mode)
- {
- sCommand.BusMode = QSPI_BUSMODE_444;
- }
- else
- {
- sCommand.BusMode = QSPI_BUSMODE_111;
- }
- if (prvQSPI_Command(&sCommand, FLASH_QSPI_TIMEOUT_DEFAULT_CNT))
- {
- return -ERROR_OPERATION_FAILED;
- }
- if (sCommand.RdData & BIT0)
- {
- return -ERROR_DEVICE_BUSY;
- }
- return ERROR_NONE;
- }
- int32_t Flash_EraseStart(uint32_t Address, uint8_t IsBlock)
- {
- FLASH_CommandTypeDef sCommand;
- Address &= (uint32_t)(0x00FFFFFF);
- while (CACHE->CACHE_CS & CACHE_IS_BUSY);
- sCommand.BusMode = QSPI_BUSMODE_111;
- sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24;
- if (prvQSPI_WriteEnable(sCommand.BusMode) != 0)
- {
- return -ERROR_OPERATION_FAILED;
- }
- if (IsBlock)
- {
- sCommand.Instruction = SPIFLASH_CMD_BE;
- }
- else
- {
- sCommand.Instruction = SPIFLASH_CMD_SE;
- }
- sCommand.Address = Address;
- if (prvQSPI_Command(&sCommand, FLASH_QSPI_TIMEOUT_DEFAULT_CNT))
- {
- return -ERROR_OPERATION_FAILED;
- }
- return ERROR_NONE;
- }
- int32_t Flash_CheckBusy(void)
- {
- return prvQSPI_IsBusy(QSPI_BUSMODE_111);
- }
- #endif
- #if 0
- int32_t __FUNC_IN_RAM__ Flash_Program(uint32_t Address, const uint8_t *pBuf, uint32_t Len)
- {
- FLASH_CommandTypeDef sCommand;
- uint32_t FinishLen = 0, DummyLen, ProgramLen, i;
- int32_t status;
- uint32_t PageData[64];
- /* Initialize the adress variables */
- sCommand.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
- sCommand.BusMode = QSPI_BUSMODE_114;
- sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
- Address &= 0x00ffffff;
- while(FinishLen < Len)
- {
- if (prvQSPI_WriteEnable(QSPI_BUSMODE_111))
- {
- return -ERROR_OPERATION_FAILED;
- }
- #if (defined __FLASH_DISABLE_IRQ__)
- __disable_irq();
- ProgramLen = ((Len - FinishLen) > 4)?4:(Len - FinishLen);
- #else
- ProgramLen = ((Len - FinishLen) > QSPI_FIFO_NUM)?QSPI_FIFO_NUM:(Len - FinishLen);
- #endif
- for(i = 0; i < ProgramLen; i+=4)
- {
- PageData[i >> 2] = BytesGetLe32(pBuf + i);
- }
- QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
- QSPI->BYTE_NUM = (ProgramLen << 16);
- sCommand.Address = Address + FinishLen;
- DummyLen = 0;
- while((DummyLen < ProgramLen) && !(QSPI->FIFO_CNTL & QUADSPI_FIFO_CNTL_TFFL))
- {
- QSPI->WR_FIFO = PageData[DummyLen >> 2];
- DummyLen += 4;
- }
- QSPI->ADDRES = (QSPI->ADDRES & ~QUADSPI_ADDRESS_ADR) | (sCommand.Address << 8);
- QSPI->FCU_CMD = (QSPI->FCU_CMD & ~(QUADSPI_FCU_CMD_CODE | QUADSPI_FCU_CMD_BUS_MODE | QUADSPI_FCU_CMD_CMD_FORMAT | QUADSPI_FCU_CMD_ACCESS_REQ)) | ((sCommand.Instruction << 24) |((uint32_t)( sCommand.BusMode<< 8)) |((uint32_t)( sCommand.CmdFormat << 4))| (FLASH_QSPI_ACCESS_REQ_ENABLE));
- while(DummyLen < ProgramLen)
- {
- while(QSPI->FIFO_CNTL & QUADSPI_FIFO_CNTL_TFFL)
- {
- }
- QSPI->WR_FIFO = PageData[DummyLen >> 2];
- DummyLen += 4;
- }
- // DBG("%u", DummyLen);
- status = -ERROR_OPERATION_FAILED;
- for (i = 0; i < FLASH_QSPI_TIMEOUT_DEFAULT_CNT; i += 4)
- {
- if (QSPI->INT_RAWSTATUS & QUADSPI_INT_RAWSTATUS_DONE_IR)
- {
- QSPI->INT_CLEAR = QUADSPI_INT_CLEAR_DONE;
- status = ERROR_NONE;
- break;
- }
- }
- if (status)
- {
- #if (defined __FLASH_DISABLE_IRQ__)
- CACHE_CleanAll(CACHE);
- __enable_irq();
- #endif
- return status;
- }
- while (prvQSPI_IsBusy(QSPI_BUSMODE_111));
- #if (defined __FLASH_DISABLE_IRQ__)
- __enable_irq();
- #endif
- FinishLen += ProgramLen;
- }
- #if (defined __FLASH_DISABLE_IRQ__)
- CACHE_CleanAll(CACHE);
- #endif
- return ERROR_NONE;
- }
- #endif
- /**
- * @brief Flash Erase Sector.
- * @param sectorAddress: The sector address to be erased
- * @retval FLASH Status: The returned value can be: QSPI_STATUS_ERROR, QSPI_STATUS_OK
- */
- uint8_t FLASH_EraseSector(uint32_t sectorAddress)
- {
- uint8_t ret;
- __disable_irq();
- //__disable_fault_irq();
- ret = ROM_QSPI_EraseSector(NULL, sectorAddress);
- //__enable_fault_irq();
- __enable_irq();
- return ret;
- }
- /**
- * @brief Flash Program Interface.
- * @param addr: specifies the address to be programmed.
- * @param size: specifies the size to be programmed.
- * @param buffer: pointer to the data to be programmed, need word aligned
- * @retval FLASH Status: The returned value can be: QSPI_STATUS_ERROR, QSPI_STATUS_OK
- */
- uint8_t FLASH_ProgramPage(uint32_t addr, uint32_t size, uint8_t *buffer)
- {
- uint8_t ret;
- QSPI_CommandTypeDef cmdType;
- cmdType.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
- cmdType.BusMode = QSPI_BUSMODE_114;
- cmdType.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
- __disable_irq();
- //__disable_fault_irq();
- ret = ROM_QSPI_ProgramPage(&cmdType, DMA_Channel_1, addr, size, buffer);
- //__enable_fault_irq();
- __enable_irq();
- return ret;
- }
- int32_t Flash_Erase(uint32_t Address, uint32_t Length)
- {
- uint32_t TotalLen = 0;
- QSPI_CommandTypeDef sCommand;
- sCommand.BusMode = QSPI_BUSMODE_111;
- sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24;
- uint32_t FlashAddress, DummyLen;
- uint8_t ret;
- while (TotalLen < Length)
- {
- FlashAddress = Address + TotalLen;
- DummyLen = Length - TotalLen;
- if (!(FlashAddress & SPI_FLASH_BLOCK_MASK) && (DummyLen >= SPI_FLASH_BLOCK_SIZE))
- {
- sCommand.Instruction = SPIFLASH_CMD_BE;
- TotalLen += SPI_FLASH_BLOCK_SIZE;
- }
- else
- {
- sCommand.Instruction = SPIFLASH_CMD_SE;
- TotalLen += SPI_FLASH_SECTOR_SIZE;
- }
- __disable_irq();
- //__disable_fault_irq();
- ret = ROM_QSPI_EraseSector(&sCommand, FlashAddress);
- //__enable_fault_irq();
- __enable_irq();
- }
- CACHE_CleanAll(CACHE);
- return ERROR_NONE;
- }
- int32_t Flash_Program(uint32_t Address, const uint8_t *pBuf, uint32_t Len)
- {
- uint32_t size = (Len + (4 - 1)) & (~(4 - 1));
- uint32_t Pos = 0;
- uint8_t ret;
- QSPI_CommandTypeDef cmdType;
- cmdType.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
- cmdType.BusMode = QSPI_BUSMODE_114;
- cmdType.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
- while(Pos < size)
- {
- if ((size - Pos) > __FLASH_PAGE_SIZE__)
- {
- __disable_irq();
- //__disable_fault_irq();
- ret = ROM_QSPI_ProgramPage(&cmdType, DMA_Channel_1, Address + Pos, __FLASH_PAGE_SIZE__, pBuf + Pos);
- //__enable_fault_irq();
- __enable_irq();
- Pos += __FLASH_PAGE_SIZE__;
- }
- else
- {
- __disable_irq();
- //__disable_fault_irq();
- ret = ROM_QSPI_ProgramPage(&cmdType, DMA_Channel_1, Address + Pos, (size - Pos), pBuf + Pos);
- //__enable_fault_irq();
- __enable_irq();
- Pos += (size - Pos);
- }
- }
- CACHE_CleanAll(CACHE);
- return ERROR_NONE;
- }
- #if 0
- int Flash_EraseSector(uint32_t address, uint8_t NeedCheck)
- {
- uint8_t buf[__FLASH_PAGE_SIZE__];
- uint32_t i;
- uint8_t retry = 1;
- void *res;
- memset(buf, 0xff, __FLASH_PAGE_SIZE__);
- BL_ERASESECTOR_AGAIN:
- FLASH_EraseSector(address);
- #if (defined __BUILD_OS__) || (defined __BUILD_APP__)
- CACHE_CleanAll(CACHE);
- #endif
- if (!NeedCheck) return ERROR_NONE;
- for(i = 0; i < 4096; i+=__FLASH_PAGE_SIZE__)
- {
- res = memcmp(address + i, buf, __FLASH_PAGE_SIZE__);
- if (res)
- {
- DBG_INFO("%x", res);
- if (retry)
- {
- retry = 0;
- goto BL_ERASESECTOR_AGAIN;
- }
- else
- {
- return -1;
- }
- }
- }
- return 0;
- }
- int Flash_ProgramData(uint32_t address, uint32_t *Data, uint32_t Len, uint8_t NeedCheck)
- {
- void *res;
- uint32_t size = (Len + (4 - 1)) & (~(4 - 1));
- FLASH_ProgramPage(address, size, Data);
- #if (defined __BUILD_OS__) || (defined __BUILD_APP__)
- CACHE_CleanAll(CACHE);
- #endif
- if (!NeedCheck) return ERROR_NONE;
- res = memcmp(address, Data, Len);
- if (res)
- {
- DBG_INFO("%x", res);
- FLASH_ProgramPage(address, size, Data);
- #if (defined __BUILD_OS__) || (defined __BUILD_APP__)
- CACHE_CleanAll(CACHE);
- #endif
- res = memcmp(address, Data, size);
- if (res)
- {
- DBG_INFO("%x", res);
- return -1;
- }
- }
- return 0;
- }
- #endif
|