From b775f36f21cf9c32c10d05132995d86a85f0b88f Mon Sep 17 00:00:00 2001 From: alexey Date: Wed, 14 Aug 2024 12:12:34 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=20FLASH=5FW?= =?UTF-8?q?rite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- memory_spi/memory_spi.c | 126 +++++++++++++++++++++++++++++----------- memory_spi/memory_spi.h | 4 +- 2 files changed, 93 insertions(+), 37 deletions(-) diff --git a/memory_spi/memory_spi.c b/memory_spi/memory_spi.c index e5111e8..893d7f0 100644 --- a/memory_spi/memory_spi.c +++ b/memory_spi/memory_spi.c @@ -24,15 +24,15 @@ - MEMSPI_CMD_Write_Enable Отправка комманды Write Enable (0x06h) - MEMSPI_CMD_Write_Disable Отправка комманды Write Disable (0x04h) - MEMSPI_CMD_Read_Data Отправка комманды Read Data (0x03h) - - MEMSPI_CMD_FLASH_Page_Program Отправка комманды Write (eeprom) (0x02h) + - MEMSPI_CMD_EEPROM_Write Отправка комманды Write (eeprom) (0x02h) - MEMSPI_CMD_FLASH_Page_Program Отправка комманды Page Program (flash) (0x02h) - MEMSPI_CMD_FLASH_Erase_Sector Отправка комманды Erase Sector (flash) (0x20h) - - MEMSPI_CMD_Fast_Read Отправка комманды Fast Read (0x0Bh) - MEMSPI_CMD_Read_JEDEC_ID Отправка комманды Read JEDEC ID (0x4Bh) - MEMSPI_CMD_Read_Device_ID Отправка комманды Read Manufacture / Device Id (0x90) ***************************************************************************/ #include "memory_spi.h" +uint8_t sector_buff[MEMSPI_SECTOR_SIZE]; //------------------------------------------------------------- //--------------------------FOR USER--------------------------- @@ -60,7 +60,7 @@ void MEMSPI_Base_Init(MEMSPI_HandleTypeDef *hmemspi) // CLOCK if(hmemspi->hspi.Instance == SPI1) - __HAL_RCC_SPI2_CLK_ENABLE(); + __HAL_RCC_SPI1_CLK_ENABLE(); else if (hmemspi->hspi.Instance == SPI2) __HAL_RCC_SPI2_CLK_ENABLE(); else if (hmemspi->hspi.Instance == SPI3) @@ -160,7 +160,7 @@ HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FL } // PROGRAM PAGES: FROM FIRST NO THE PREVIOUS TO THE LAST - hmemspi->hNextAddr = FLASH_Address; // address would increase automatically in this variable + hmemspi->hNextAddr = FLASH_Address; // address would automatically increase in this variable for(int i = 0; i < lastpage - firstpage; i++) { MEMSPI_Status = MEMSPI_EEPROM_Write_Page(hmemspi, hmemspi->hNextAddr, &pData[bytecnt], currentpage_size, &Timeout, &tickstart, 0); // programm page @@ -197,16 +197,32 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write uint32_t timeoutcnt = Timeout; uint8_t *writebuff = WriteInit->pDataPtr; HAL_StatusTypeDef MEMSPI_Status; - - // ERASE FLASH - MEMSPI_Status = MEMSPI_FLASH_Erase(hmemspi, WriteInit->Sector_Address, WriteInit->Sector_Size, Timeout, 0); - if(MEMSPI_Status != HAL_OK) // note: no need waiting for end: the next call will wait for unbusy - return MEMSPI_Status; + // CHECK FOR UNDEFINED STRUCTURE + if (WriteInit->Sector_Size == 0) // if sector undefined + { // fill it with data init + WriteInit->Sector_Address = WriteInit->Data_Address; + WriteInit->Sector_Size = WriteInit->Data_Size; + } + else if (WriteInit->Data_Size == 0) // if data undefined + { // fill it with sector init + WriteInit->Data_Address = WriteInit->Sector_Address; + WriteInit->Data_Size = WriteInit->Sector_Size; + } // if both undefined - return HAL ERR + else if ((WriteInit->Sector_Size == 0) && (WriteInit->Data_Size == 0)) + { + return HAL_ERROR; + } + // CHECK FOR CORRECT STRUCTURE + // if data is beyound sector + if((WriteInit->Data_Address < WriteInit->Sector_Address) || + ((WriteInit->Data_Address + WriteInit->Data_Size) > (WriteInit->Sector_Address + WriteInit->Sector_Size))) + return HAL_ERROR; + // WRITE FLASH WITH SAVING PREVIOUS DATA if(WriteInit->fSavePrevoisData) { - uint8_t sector_buff[WriteInit->Sector_Size]; +// uint8_t sector_buff[WriteInit->Sector_Size]; // store data from flash MEMSPI_Status = MEMSPI_Read_Memory(hmemspi, WriteInit->Sector_Address, sector_buff, WriteInit->Sector_Size, Timeout); if(MEMSPI_Status != HAL_OK) @@ -219,26 +235,62 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write sector_buff[addr_shift+i] = WriteInit->pDataPtr[addr_shift+i]; } - writebuff = sector_buff; // set pointer to buffer that need to be restored + // CALC AREA TO REPROGRAM + uint16_t lastsector_size = WriteInit->Sector_Size; + uint16_t firstsector = (WriteInit->Sector_Address/MEMSPI_SECTOR_SIZE); + uint16_t lastsector = ((WriteInit->Sector_Address+WriteInit->Sector_Size-1)/MEMSPI_SECTOR_SIZE); + if(firstsector != lastsector) // if area is on several pages + { + lastsector_size = (WriteInit->Sector_Address+WriteInit->Sector_Size) - lastsector*MEMSPI_SECTOR_SIZE; // set size of data on last page + } + // REPROGRAM SECTORS: FROM FIRST SECTOR NO THE PREVIOUS TO THE LAST + hmemspi->hNextAddr = WriteInit->Sector_Address; // address would automatically increase in this variable + hmemspi->hNextSector = firstsector+1; + uint16_t bytescnt = 0; + uint16_t bytes_to_next_sector = 0; + for(int i = 0; i < (lastsector - firstsector); i++) + { + // ERASE FLASH + MEMSPI_Status = MEMSPI_FLASH_Erase(hmemspi, hmemspi->hNextAddr, 1, Timeout, 0); + if(MEMSPI_Status != HAL_OK) // note: no need waiting for end: the next call will wait for unbusy + return MEMSPI_Status; + + // PROGRAM FLASH WITH NEW DATA + // calc bytes to next sector + bytes_to_next_sector = hmemspi->hNextSector*MEMSPI_SECTOR_SIZE - hmemspi->hNextAddr; + // program data to flash + MEMSPI_Status = MEMSPI_FLASH_Program(hmemspi, hmemspi->hNextAddr, §or_buff[bytescnt], bytes_to_next_sector, Timeout, 0); + if(MEMSPI_Status != HAL_OK) + return MEMSPI_Status; + // shift bytes count to data, that shoud be on the next page + bytescnt += bytes_to_next_sector; + } - // PROGRAM FLASH WITH NEW DATA - // program data to flash - MEMSPI_Status = MEMSPI_FLASH_Program(hmemspi, WriteInit->Sector_Address, writebuff, WriteInit->Sector_Size, Timeout, 1); - if(MEMSPI_Status != HAL_OK) + // ERASE FLASH + MEMSPI_Status = MEMSPI_FLASH_Erase(hmemspi, hmemspi->hNextAddr, 1, Timeout, 0); + if(MEMSPI_Status != HAL_OK) // note: no need waiting for end: the next call will wait for unbusy return MEMSPI_Status; + + // PROGRAM LAST SECTOR + MEMSPI_Status = MEMSPI_FLASH_Program(hmemspi, hmemspi->hNextAddr, §or_buff[bytescnt], lastsector_size, Timeout, WaitForEnd); + if(MEMSPI_Status != HAL_OK) + return MEMSPI_Status; } // WRITE FLASH WITHOUT SAVING PREVIOUS DATA else { + // ERASE FLASH + MEMSPI_Status = MEMSPI_FLASH_Erase(hmemspi, WriteInit->Sector_Address, WriteInit->Sector_Size, Timeout, 0); + if(MEMSPI_Status != HAL_OK) // note: no need waiting for end: the next call will wait for unbusy + return MEMSPI_Status; + // PROGRAM FLASH WITH NEW DATA - timeoutcnt = HAL_GetTick() - tickstart; // update timeout - Timeout -= timeoutcnt; - tickstart += timeoutcnt; // program data to flash - MEMSPI_Status = MEMSPI_FLASH_Program(hmemspi, WriteInit->Sector_Address, writebuff, WriteInit->Sector_Size, Timeout, WaitForEnd); + MEMSPI_Status = MEMSPI_FLASH_Program(hmemspi, WriteInit->Sector_Address, WriteInit->pDataPtr, WriteInit->Sector_Size, Timeout, WaitForEnd); if(MEMSPI_Status != HAL_OK) return MEMSPI_Status; } + return HAL_OK; } @@ -259,30 +311,30 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t F HAL_StatusTypeDef MEMSPI_Status; // CALC AREA TO PROGRAM - uint16_t bytecnt = 0; - uint16_t currentpage_size = 0; uint16_t lastpage_size = Size; uint16_t firstpage = (FLASH_Address/MEMSPI_PAGE_SIZE); uint16_t lastpage = ((FLASH_Address+Size-1)/MEMSPI_PAGE_SIZE); if(firstpage != lastpage) // if area is on several pages { - currentpage_size = (firstpage+1)*MEMSPI_PAGE_SIZE - FLASH_Address; // set size of data on first page lastpage_size = (FLASH_Address+Size) - lastpage*MEMSPI_PAGE_SIZE; // set size of data on last page } // PROGRAM PAGES: FROM FIRST NO THE PREVIOUS TO THE LAST - hmemspi->hNextAddr = FLASH_Address; // address would increase automatically in this variable + hmemspi->hNextAddr = FLASH_Address; // address would automatically increase in this variable + hmemspi->hNextPage = firstpage+1; // address would automatically increase in this variable + uint16_t bytecnt = 0; + uint16_t bytes_to_next_page = 0; for(int i = 0; i < lastpage - firstpage; i++) { - MEMSPI_Status = MEMSPI_FLASH_Program_Page(hmemspi, hmemspi->hNextAddr, &pData[bytecnt], currentpage_size, &Timeout, &tickstart, 0); // programm page + // calc bytes to next sector + bytes_to_next_page = hmemspi->hNextPage*MEMSPI_PAGE_SIZE - hmemspi->hNextAddr; + + MEMSPI_Status = MEMSPI_FLASH_Program_Page(hmemspi, hmemspi->hNextAddr, &pData[bytecnt], bytes_to_next_page, &Timeout, &tickstart, 0); // programm page if(MEMSPI_Status != HAL_OK) // note: no need waiting for end: the next call will wait for unbusy return MEMSPI_Status; - - // note for multiple page program: first we program rest of the first page, + // then we shift byte count to data, that shoud be on the next page - bytecnt += currentpage_size; - // and set current size as page size. because next pages will be fully programmed - currentpage_size = MEMSPI_PAGE_SIZE; + bytecnt += bytes_to_next_page; } // PROGRAM LAST PAGE @@ -381,7 +433,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint3 return HAL_TIMEOUT; // return timeout // erase sector (instruction) - MEMSPI_CMD_FLASH_Erase_Sector(hmemspi, FLASH_Address, *Timeout); + MEMSPI_Status = MEMSPI_CMD_FLASH_Erase_Sector(hmemspi, FLASH_Address, *Timeout); if(MEMSPI_Status != HAL_OK) return MEMSPI_Status; @@ -430,8 +482,8 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program_Page(MEMSPI_HandleTypeDef *hmemspi, uint3 // update handle variables hmemspi->hNextAddr = (FLASH_Address+Size); - hmemspi->hNextPage = (FLASH_Address+Size)/MEMSPI_PAGE_SIZE; - hmemspi->hNextSector = (FLASH_Address+Size)/MEMSPI_SECTOR_SIZE; + hmemspi->hNextPage = (hmemspi->hNextAddr+Size)/MEMSPI_PAGE_SIZE; + hmemspi->hNextSector = (hmemspi->hNextAddr+Size)/MEMSPI_SECTOR_SIZE; return HAL_OK; } @@ -591,13 +643,17 @@ HAL_StatusTypeDef MEMSPI_CMD_Read_Status_Register(MEMSPI_HandleTypeDef *hmemspi, HAL_StatusTypeDef MEMSPI_CMD_Write_Status_Register(MEMSPI_HandleTypeDef *hmemspi, uint16_t WrittenBits, uint32_t Timeout) { HAL_StatusTypeDef SPI_RES; - uint8_t command[2]; + uint8_t command[3]; + uint8_t size; command[0] = MEMSPI_WRITE_STATUS_REG; - command[1] = WrittenBits >> 2; + command[1] = WrittenBits; + command[2] = WrittenBits >> 8; + + size = 3; MEMSPI_Select(hmemspi); - SPI_RES = MEMSPI_SPI_Transmit(hmemspi, command, 1, Timeout); + SPI_RES = MEMSPI_SPI_Transmit(hmemspi, command, size, Timeout); MEMSPI_Deselect(hmemspi); return SPI_RES; diff --git a/memory_spi/memory_spi.h b/memory_spi/memory_spi.h index dd3df35..1c33a42 100644 --- a/memory_spi/memory_spi.h +++ b/memory_spi/memory_spi.h @@ -8,8 +8,8 @@ #include "gpio_general.h" /////////////////////////---USER SETTINGS---///////////////////////// -//#define EXT_FLASH -#define EXT_EEPROM +#define EXT_FLASH +//#define EXT_EEPROM #if defined(EXT_FLASH) & defined(EXT_EEPROM) #error Choose only one memory