Исправлено запись eeprom: теперь возможна запись большей одной страницы
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
- MEMSPI_Base_Init Инициализация SPI и GPIO для FLASH
|
||||
|
||||
@func service
|
||||
- MEMSPI_EEPROM_Write_Page Запись страницы в EEPROM *есть более общая функция MEMSPI_EEPROM_Write, которая записывает участки больше страницы
|
||||
- MEMSPI_FLASH_Erase_Sector Очистка сектора FLASH. *есть более общая функция MEMSPI_FLASH_Erase, которая может ощичать несколько секторов
|
||||
- MEMSPI_FLASH_Program_Page Программирование страницы. *есть более общая функция MEMSPI_FLASH_Program, которая программирует участки больше страницы
|
||||
- MEMSPI_WriteEnablingUntilTimeout Разрешение записи, пока не будет ответа или не истек таймаут
|
||||
@@ -134,38 +135,53 @@ HAL_StatusTypeDef MEMSPI_Read_Memory(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read external FLASH/EEPROM.
|
||||
* @brief Write external EEPROM.
|
||||
* @param hmemspi - указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address - адресс куда начинать записывать.
|
||||
* @param pData - откуда брать данные для записи в EEPROM.
|
||||
* @param Size - сколько байтов записать.
|
||||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||||
* @param Timeout - время, за которое должна быть осуществлена запись.
|
||||
* @param WaitForEnd - ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
* @note Включает в себя проверку на доступность памяти (флаг BUSY)
|
||||
* @note Позволяет записать участок памяти. Можно записывать несколько страниц.
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd)
|
||||
{
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
|
||||
// enable writting and waiting for unbusy
|
||||
if(MEMSPI_WriteEnablingUntilTimeout(hmemspi, &Timeout, &tickstart) != HAL_OK) // if writting isnt enable
|
||||
return HAL_TIMEOUT; // return timeout
|
||||
// CALC AREA TO WRITE
|
||||
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
|
||||
}
|
||||
|
||||
MEMSPI_Status = MEMSPI_CMD_EEPROM_Write(hmemspi, FLASH_Address, pData, Size, Timeout);
|
||||
// PROGRAM PAGES: FROM FIRST NO THE PREVIOUS TO THE LAST
|
||||
hmemspi->hNextAddr = FLASH_Address; // address would increase automatically 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
|
||||
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;
|
||||
}
|
||||
|
||||
// PROGRAM LAST PAGE
|
||||
MEMSPI_Status = MEMSPI_FLASH_Program_Page(hmemspi, hmemspi->hNextAddr, &pData[bytecnt], lastpage_size, &Timeout, &tickstart, WaitForEnd); // programm page
|
||||
if(MEMSPI_Status != HAL_OK)
|
||||
return MEMSPI_Status;
|
||||
|
||||
// waiting for ending of writting if need
|
||||
if(WaitForEnd)
|
||||
if(MEMSPI_WaitOnFlagUntilTimeout(hmemspi, MEMSPI_SR_WEL|MEMSPI_SR_BUSY, 0, &Timeout, &tickstart) != HAL_OK) // if writting isnt done (MEMSPI busy and WEL bit isnt in reset state)
|
||||
return HAL_TIMEOUT;
|
||||
|
||||
// update handle variables
|
||||
hmemspi->hNextAddr = (FLASH_Address+Size);
|
||||
hmemspi->hNextPage = (FLASH_Address+Size)/MEMSPI_PAGE_SIZE;
|
||||
hmemspi->hNextSector = (FLASH_Address+Size)/MEMSPI_SECTOR_SIZE;
|
||||
return HAL_OK;
|
||||
}
|
||||
/**
|
||||
@@ -191,7 +207,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write
|
||||
|
||||
// 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
|
||||
if(MEMSPI_Status != HAL_OK) // note: no need waiting for end: the next call will wait for unbusy
|
||||
return MEMSPI_Status;
|
||||
|
||||
// WRITE FLASH WITH SAVING PREVIOUS DATA
|
||||
@@ -266,7 +282,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t F
|
||||
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
|
||||
if(MEMSPI_Status != HAL_OK) // note: no need waiting for end
|
||||
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,
|
||||
@@ -316,6 +332,43 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------
|
||||
//----------------------SERVICE FUNCTIONS----------------------
|
||||
/**
|
||||
* @brief Write page in external EEPROM.
|
||||
* @param hmemspi - указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address - адресс куда начинать записывать.
|
||||
* @param pData - откуда брать данные для записи в EEPROM.
|
||||
* @param Size - сколько байтов записать.
|
||||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||||
* @param WaitForEnd - ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
* @note Позволяет записывать только байты в пределах одной страницы.
|
||||
Для более гибкой записи есть функция MEMSPI_EEPROM_Write, которая программирует участки любой длины (в теории).
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_EEPROM_Write_Page(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd)
|
||||
{
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
// enable writting and waiting for unbusy
|
||||
if(MEMSPI_WriteEnablingUntilTimeout(hmemspi, Timeout, tickstart) != HAL_OK) // if writting isnt enable
|
||||
return HAL_TIMEOUT; // return timeout
|
||||
|
||||
MEMSPI_Status = MEMSPI_CMD_EEPROM_Write(hmemspi, FLASH_Address, pData, Size, *Timeout);
|
||||
if(MEMSPI_Status != HAL_OK)
|
||||
return MEMSPI_Status;
|
||||
|
||||
// waiting for ending of writting if need
|
||||
if(WaitForEnd)
|
||||
if(MEMSPI_WaitOnFlagUntilTimeout(hmemspi, MEMSPI_SR_WEL|MEMSPI_SR_BUSY, 0, Timeout, tickstart) != HAL_OK) // if writting isnt done (MEMSPI busy and WEL bit isnt in reset state)
|
||||
return HAL_TIMEOUT;
|
||||
|
||||
// update handle variables
|
||||
hmemspi->hNextAddr = (FLASH_Address+Size);
|
||||
hmemspi->hNextPage = (FLASH_Address+Size)/MEMSPI_PAGE_SIZE;
|
||||
hmemspi->hNextSector = (FLASH_Address+Size)/MEMSPI_SECTOR_SIZE;
|
||||
return HAL_OK;
|
||||
}
|
||||
/**
|
||||
* @brief Erase external FLASH Sector.
|
||||
* @param hmemspi - указатель на хендл внешней памяти.
|
||||
@@ -400,25 +453,20 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program_Page(MEMSPI_HandleTypeDef *hmemspi, uint3
|
||||
HAL_StatusTypeDef MEMSPI_WriteEnablingUntilTimeout(MEMSPI_HandleTypeDef *hmemspi, uint32_t *Timeout, uint32_t *tickstart)
|
||||
{
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
// enable writting
|
||||
MEMSPI_Status = MEMSPI_CMD_Write_Enable(hmemspi, *Timeout);
|
||||
if(MEMSPI_Status != HAL_OK)
|
||||
return MEMSPI_Status;
|
||||
|
||||
// check is writting enabled
|
||||
MEMSPI_Status = MEMSPI_CMD_Read_Status_Register(hmemspi, MEMSPI_SR_WEL|MEMSPI_SR_BUSY, 0, *Timeout);
|
||||
if(MEMSPI_Status != HAL_OK)
|
||||
return MEMSPI_Status;
|
||||
// wait for unbusy
|
||||
if(MEMSPI_WaitOnFlagUntilTimeout(hmemspi, MEMSPI_SR_BUSY, 0, Timeout, tickstart) != HAL_OK) // if its unbusy for timeout
|
||||
return HAL_TIMEOUT;
|
||||
|
||||
// enable writing
|
||||
while((hmemspi->SR&MEMSPI_SR_WEL) != MEMSPI_SR_WEL)
|
||||
{
|
||||
// if flash isnt busy - set WEL flag
|
||||
if((hmemspi->SR&MEMSPI_SR_BUSY) == 0)
|
||||
MEMSPI_CMD_Write_Enable(hmemspi, *Timeout);
|
||||
|
||||
// check is writting enabled
|
||||
// MEMSPI_Status = MEMSPI_CMD_Read_Status_Register(hmemspi, MEMSPI_SR_WEL|MEMSPI_SR_BUSY, *Timeout);
|
||||
MEMSPI_Status = MEMSPI_SPI_Receive(hmemspi, (uint8_t *)&hmemspi->SR, 1, *Timeout); // receive response
|
||||
// check is writting enabled
|
||||
MEMSPI_Status = MEMSPI_CMD_Read_Status_Register(hmemspi, MEMSPI_SR_WEL|MEMSPI_SR_BUSY, 1, *Timeout);
|
||||
if(MEMSPI_Status != HAL_OK)
|
||||
{
|
||||
MEMSPI_Deselect(hmemspi);
|
||||
|
||||
@@ -155,15 +155,15 @@ void MEMSPI_Base_Init(MEMSPI_HandleTypeDef *hmemspi);
|
||||
HAL_StatusTypeDef MEMSPI_Read_Memory(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size, uint32_t Timeout);
|
||||
|
||||
/**
|
||||
* @brief Read external FLASH/EEPROM.
|
||||
* @brief Write external EEPROM.
|
||||
* @param hmemspi - указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address - адресс куда начинать записывать.
|
||||
* @param pData - откуда брать данные для записи в EEPROM.
|
||||
* @param Size - сколько байтов записать.
|
||||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||||
* @param Timeout - время, за которое должна быть осуществлена запись.
|
||||
* @param WaitForEnd - ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
* @note Включает в себя проверку на доступность памяти (флаг BUSY)
|
||||
* @note Позволяет записать участок памяти. Можно записывать несколько страниц.
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd);
|
||||
|
||||
@@ -208,6 +208,20 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
////////////////////////---SERVICE FUNCTIONS---//////////////////////
|
||||
/**
|
||||
* @brief Write page in external EEPROM.
|
||||
* @param hmemspi - указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address - адресс куда начинать записывать.
|
||||
* @param pData - откуда брать данные для записи в EEPROM.
|
||||
* @param Size - сколько байтов записать.
|
||||
* @param Timeout - время, за которое должна быть осуществлена запись.
|
||||
* @param tickstart - время, относительно которого надо отсчитывать таймаут.
|
||||
* @param WaitForEnd - ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
* @note Позволяет записывать только байты в пределах одной страницы.
|
||||
Для более гибкой записи есть функция MEMSPI_EEPROM_Write, которая программирует участки любой длины (в теории).
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_EEPROM_Write_Page(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd);
|
||||
/**
|
||||
* @brief Erase external FLASH Sector.
|
||||
* @param hmemspi - указатель на хендл внешней памяти.
|
||||
@@ -227,7 +241,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint3
|
||||
* @param FLASH_Address - адресс куда начинать записывать.
|
||||
* @param pData - откуда брать данные для записи в FLASH.
|
||||
* @param Size - сколько байтов записать.
|
||||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||||
* @param Timeout - время, за которое должна быть осуществлена запись.
|
||||
* @param tickstart - время, относительно которого надо отсчитывать таймаут.
|
||||
* @param WaitForEnd - ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
|
||||
Reference in New Issue
Block a user