Большой апгрейд:
- исправлены баги библиотеки memspi - добавлены модули для сохранения настреок в eeprom и flash (с равномерным износом) - надо тестить, проверять и рефакторить
This commit is contained in:
312
Src/memspi.c
312
Src/memspi.c
@@ -21,6 +21,7 @@
|
||||
#include "memspi.h"
|
||||
uint8_t sector_buff[MEMSPI_SECTOR_SIZE];
|
||||
|
||||
MEMSPI_HandleTypeDef memory_spi;
|
||||
//-------------------------------------------------------------
|
||||
//--------------------------FOR USER---------------------------
|
||||
/**
|
||||
@@ -63,7 +64,7 @@ void MEMSPI_Base_Init(MEMSPI_HandleTypeDef *hmemspi, SPI_HandleTypeDef *hspi)
|
||||
* @return HAL status.
|
||||
* @note Включает в себя проверку на доступность памяти (флаг BUSY)
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_Read_Memory(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size, uint32_t Timeout)
|
||||
HAL_StatusTypeDef MEMSPI_Read_Memory(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint32_t Size, uint32_t Timeout)
|
||||
{
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
uint32_t tickstart = local_time();
|
||||
@@ -90,7 +91,7 @@ HAL_StatusTypeDef MEMSPI_Read_Memory(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA
|
||||
* @return HAL status.
|
||||
* @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)
|
||||
HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_t Size, uint32_t Timeout, uint8_t WaitForEnd)
|
||||
{
|
||||
uint32_t tickstart = local_time();
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
@@ -180,7 +181,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write
|
||||
uint32_t addr_shift = WriteInit->Data_Address - WriteInit->Sector_Address;
|
||||
for(int i = 0; i < WriteInit->Data_Size; i++)
|
||||
{
|
||||
sector_buff[addr_shift+i] = WriteInit->pDataPtr[addr_shift+i];
|
||||
sector_buff[addr_shift+i] = WriteInit->pDataPtr[i];
|
||||
}
|
||||
|
||||
// CALC AREA TO REPROGRAM
|
||||
@@ -243,54 +244,57 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program external FLASH.
|
||||
* @param hmemspi Указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address Адресс куда начинать записывать.
|
||||
* @param pData Откуда брать данные для записи в FLASH.
|
||||
* @param Size Вколько байтов записать.
|
||||
* @param Timeout Время, за которое должно быть осуществлено чтение.
|
||||
* @param WaitForEnd Ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
* @note Программирование участка памяти, без ограничений на кол-во байт
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd)
|
||||
* @brief Program external FLASH.
|
||||
* @param hmemspi - указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address - адресс куда начинать записывать.
|
||||
* @param pData - откуда брать данные для записи в FLASH.
|
||||
* @param Size - сколько байтов записать.
|
||||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||||
* @param WaitForEnd - ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
* @note Программирование участка памяти, без ограничений на кол-во байт
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_t Size, uint32_t Timeout, uint8_t WaitForEnd)
|
||||
{
|
||||
uint32_t tickstart = local_time();
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
|
||||
// CALC AREA TO PROGRAM
|
||||
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
|
||||
{
|
||||
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 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++)
|
||||
{
|
||||
// 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;
|
||||
|
||||
// then we shift byte count to data, that shoud be on the next page
|
||||
bytecnt += bytes_to_next_page;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
return HAL_OK; // if all ok return HAL_OK
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
|
||||
#ifdef FLASHTYPE_BYTE_PROGRAMM
|
||||
// PROGRAM DATA: FROM FIRST BYTE TO THE LAST
|
||||
MEMSPI_Status = MEMSPI_FLASH_Program_Bytes(hmemspi, FLASH_Address, pData, Size, &Timeout, &tickstart, WaitForEnd); // programm data
|
||||
if(MEMSPI_Status != HAL_OK)
|
||||
return MEMSPI_Status;
|
||||
#else
|
||||
// CALC AREA TO PROGRAM
|
||||
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
|
||||
{
|
||||
lastpage_size = (FLASH_Address+Size) - lastpage*MEMSPI_PAGE_SIZE; // set size of data on last page
|
||||
}
|
||||
|
||||
// PROGRAM PAGES: FROM FIRST PAGE TO THE PREVIOUS TO THE LAST
|
||||
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;
|
||||
for(int i = 0; i < lastpage - firstpage; i++)
|
||||
{
|
||||
// calc bytes to next sector
|
||||
hmemspi->TxSize = hmemspi->hNextPage*MEMSPI_PAGE_SIZE - hmemspi->hNextAddr;
|
||||
|
||||
MEMSPI_Status = MEMSPI_FLASH_Program_Page(hmemspi, hmemspi->hNextAddr, &pData[bytecnt], hmemspi->TxSize, &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;
|
||||
// then we shift byte count to data, that shoud be on the next page
|
||||
bytecnt += hmemspi->TxSize;
|
||||
}
|
||||
// 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;
|
||||
#endif
|
||||
return HAL_OK; // if all ok return HAL_OK
|
||||
}
|
||||
|
||||
|
||||
@@ -305,7 +309,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t F
|
||||
* @note Т.к. очитска происходит по секторам, Size нужен, чтобы определить сколько секторов очистить
|
||||
* И если начальны адресс будет на Sector 0, а последний байт на Sector 1, то произойдет очистка Sector 0 и Sector 1
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd)
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t Size, uint32_t Timeout, uint8_t WaitForEnd)
|
||||
{
|
||||
uint32_t tickstart = local_time();
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
@@ -325,7 +329,70 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set protection for FLASH sectors.
|
||||
* @param hmemspi Указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address Адресс сектора для выставления защиты.
|
||||
* @param Size Сколько байтов защитить.
|
||||
* @param ProtectState Состояние защиты: ENABLE / DISABLE.
|
||||
* @param Timeout Время, за которое должно быть осуществлено выставление защиты.
|
||||
* @return HAL status.
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Protection(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t Size, uint32_t ProtectState, uint32_t Timeout)
|
||||
{
|
||||
#ifdef MEMSPI_PROTECT_SECTOR
|
||||
uint32_t tickstart = local_time();
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
|
||||
// CALC AREA TO PROTECT
|
||||
uint16_t bytecnt = 0;
|
||||
uint16_t firstsector = (FLASH_Address/MEMSPI_SECTOR_SIZE);
|
||||
uint16_t lastsector = ((FLASH_Address+Size-1)/MEMSPI_SECTOR_SIZE);
|
||||
|
||||
for(int i = 0; i <= (lastsector - firstsector); i++)
|
||||
{
|
||||
|
||||
if(MEMSPI_WriteEnablingUntilTimeout(hmemspi, &Timeout, &tickstart) != HAL_OK) // if writting isnt enable
|
||||
return HAL_TIMEOUT; // return timeout
|
||||
|
||||
if(ProtectState == ENABLE)
|
||||
{
|
||||
MEMSPI_Status = MEMSPI_CMD_Protect_Sector(hmemspi, FLASH_Address, Timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
MEMSPI_Status = MEMSPI_CMD_Unprotect_Sector(hmemspi, FLASH_Address, Timeout);
|
||||
}
|
||||
|
||||
if(MEMSPI_WaitOnFlagsUntilTimeout(hmemspi, MEMSPI_SR_WEL|MEMSPI_SR_BUSY, 0, &Timeout, &tickstart) != HAL_OK) // if operation isnt done (MEMSPI busy and WEL bit isnt in reset state)
|
||||
return HAL_TIMEOUT; // return timeout because erasing instruction accepted, but arent done
|
||||
|
||||
uint8_t ProtectStateCheck;
|
||||
if(MEMSPI_CMD_Read_Sector_Protection(hmemspi, FLASH_Address, &ProtectStateCheck, Timeout) == HAL_OK)
|
||||
{
|
||||
uint8_t expectedState = (ProtectState == ENABLE) ? 0xFF : 0x00;
|
||||
if(ProtectStateCheck == expectedState)
|
||||
{
|
||||
// return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
FLASH_Address += MEMSPI_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
|
||||
return MEMSPI_Status;
|
||||
#else
|
||||
return HAL_ERROR;
|
||||
#endif
|
||||
}
|
||||
//-------------------------------------------------------------
|
||||
//----------------------SERVICE FUNCTIONS----------------------
|
||||
/**
|
||||
@@ -341,7 +408,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA
|
||||
* @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_EEPROM_Write_Page(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd)
|
||||
{
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
// enable writting and waiting for unbusy
|
||||
@@ -397,45 +464,114 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint3
|
||||
|
||||
/**
|
||||
* @brief Program page in external FLASH.
|
||||
* @param hmemspi Указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address Адресс куда начинать записывать.
|
||||
* @param pData Откуда брать данные для записи в FLASH.
|
||||
* @param Size Вколько байтов записать.
|
||||
* @param Timeout Время, за которое должно быть осуществлено чтение.
|
||||
* @param tickstart Время, относительно которого надо отсчитывать таймаут.
|
||||
* @param WaitForEnd Ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
* @note Позволяет перепрограммировать только байты в прелелах одной страницы.
|
||||
Для более гибкого программирования есть функция MEMSPI_FLASH_Program, которая программирует участки любой длины (в теории).
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program_Page(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd)
|
||||
* @param hmemspi - указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address - адресс куда начинать записывать.
|
||||
* @param pData - откуда брать данные для записи в FLASH.
|
||||
* @param Size - сколько байтов записать.
|
||||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||||
* @param tickstart - время, относительно которого надо отсчитывать таймаут.
|
||||
* @param WaitForEnd - ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
* @note Позволяет перепрограммировать только байты в прелелах одной страницы.
|
||||
Для более гибкого программирования есть функция MEMSPI_FLASH_Program, которая программирует участки любой длины (в теории).
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program_Page(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_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
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
|
||||
// check if flash range is placed at one page
|
||||
if((FLASH_Address/MEMSPI_PAGE_SIZE) != ((FLASH_Address+Size-1)/MEMSPI_PAGE_SIZE)) // if page of first byte isnt equal page of last byte
|
||||
return HAL_ERROR; // return error
|
||||
#ifndef FLASHTYPE_BYTE_PROGRAMM
|
||||
// PROGRAM WHOLE PAGE
|
||||
// enable writting and waiting for unbusy
|
||||
if(MEMSPI_WriteEnablingUntilTimeout(hmemspi, &Timeout, &tickstart) != HAL_OK) // if writting isnt enable
|
||||
return HAL_TIMEOUT; // return timeout
|
||||
|
||||
// check if flash range is placed at one page
|
||||
if((FLASH_Address/MEMSPI_PAGE_SIZE) != ((FLASH_Address+Size-1)/MEMSPI_PAGE_SIZE)) // if page of first byte isnt equal page of last byte
|
||||
return HAL_ERROR; // return error
|
||||
|
||||
// programm page (instruction)
|
||||
MEMSPI_Status = MEMSPI_CMD_FLASH_Page_Program(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_WaitOnFlagsUntilTimeout(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;
|
||||
#else
|
||||
// PROGRAM PAGE BY BYTES
|
||||
|
||||
// programm page (instruction)
|
||||
MEMSPI_Status = MEMSPI_CMD_FLASH_Page_Program(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_WaitOnFlagsUntilTimeout(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 = (hmemspi->hNextAddr+Size)/MEMSPI_PAGE_SIZE;
|
||||
hmemspi->hNextSector = (hmemspi->hNextAddr+Size)/MEMSPI_SECTOR_SIZE;
|
||||
|
||||
return HAL_OK;
|
||||
for(int j = 0; j < MEMSPI_PAGE_SIZE; j++)
|
||||
{
|
||||
// enable writting and waiting for unbusy
|
||||
if(MEMSPI_WriteEnablingUntilTimeout(hmemspi, Timeout, tickstart) != HAL_OK) // if writting isnt enable
|
||||
return HAL_TIMEOUT; // return timeout
|
||||
|
||||
// check if flash range is placed at one page
|
||||
if((FLASH_Address/MEMSPI_PAGE_SIZE) != ((FLASH_Address+Size-1)/MEMSPI_PAGE_SIZE)) // if page of first byte isnt equal page of last byte
|
||||
return HAL_ERROR; // return error
|
||||
|
||||
// programm page (instruction)
|
||||
MEMSPI_Status = MEMSPI_CMD_FLASH_Byte_Program(hmemspi, FLASH_Address, pData[j], *Timeout);
|
||||
if(MEMSPI_Status != HAL_OK)
|
||||
return MEMSPI_Status;
|
||||
|
||||
// waiting for ending of writting if need
|
||||
if(WaitForEnd)
|
||||
if(MEMSPI_WaitOnFlagsUntilTimeout(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;
|
||||
}
|
||||
#endif
|
||||
|
||||
// update handle variables
|
||||
hmemspi->hNextAddr = (FLASH_Address+Size);
|
||||
hmemspi->hNextPage = (hmemspi->hNextAddr+Size)/MEMSPI_PAGE_SIZE;
|
||||
hmemspi->hNextSector = (hmemspi->hNextAddr+Size)/MEMSPI_SECTOR_SIZE;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program data in external FLASH in blocking mode.
|
||||
* @param hmemspi - указатель на хендл внешней памяти.
|
||||
* @param FLASH_Address - адресс куда начинать записывать.
|
||||
* @param pData - откуда брать данные для записи в FLASH.
|
||||
* @param Size - сколько байтов записать.
|
||||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||||
* @param tickstart - время, относительно которого надо отсчитывать таймаут.
|
||||
* @param WaitForEnd - ожидание, пока память не выполненит операцию.
|
||||
* @return HAL status.
|
||||
* @note Позволяет перепрограммировать любое количество байт (без ограничений на количество страниц)
|
||||
*/
|
||||
HAL_StatusTypeDef MEMSPI_FLASH_Program_Bytes(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint32_t Size, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd)
|
||||
{
|
||||
HAL_StatusTypeDef MEMSPI_Status;
|
||||
|
||||
for(int j = 0; j < Size; j++)
|
||||
{
|
||||
// enable writting and waiting for unbusy
|
||||
if(MEMSPI_WriteEnablingUntilTimeout(hmemspi, Timeout, tickstart) != HAL_OK) // if writting isnt enable
|
||||
return HAL_TIMEOUT; // return timeout
|
||||
|
||||
// programm page (instruction)
|
||||
MEMSPI_Status = MEMSPI_CMD_FLASH_Byte_Program(hmemspi, FLASH_Address+j, pData[j], *Timeout);
|
||||
if(MEMSPI_Status != HAL_OK)
|
||||
return MEMSPI_Status;
|
||||
|
||||
// waiting for ending of writting if need
|
||||
if(WaitForEnd)
|
||||
if(MEMSPI_WaitOnFlagsUntilTimeout(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 = (hmemspi->hNextAddr+Size)/MEMSPI_PAGE_SIZE;
|
||||
hmemspi->hNextSector = (hmemspi->hNextAddr+Size)/MEMSPI_SECTOR_SIZE;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setting WEL bit until it setted or until timeout.
|
||||
* @param hmemspi Указатель на хендл внешней памяти.
|
||||
|
||||
Reference in New Issue
Block a user