Улучшена функция FLASH_Write
This commit is contained in:
@@ -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
|
||||
@@ -198,15 +198,31 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write
|
||||
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, WriteInit->Sector_Address, writebuff, WriteInit->Sector_Size, Timeout, 1);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user