diff --git a/memory_spi/memory_spi.c b/memory_spi/memory_spi.c index 30711a7..a8eadd9 100644 --- a/memory_spi/memory_spi.c +++ b/memory_spi/memory_spi.c @@ -140,10 +140,11 @@ HAL_StatusTypeDef MEMSPI_Read_Memory(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA * @param pData - откуда брать данные для записи в EEPROM. * @param Size - сколько байтов записать. * @param Timeout - время, за которое должно быть осуществлено чтение. + * @param WaitForEnd - ожидание, пока память не выполненит операцию. * @return HAL status. * @note Включает в себя проверку на доступность памяти (флаг BUSY) */ -HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout) +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; @@ -156,9 +157,10 @@ HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FL if(MEMSPI_Status != HAL_OK) return MEMSPI_Status; - // waiting for ending of writting - 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; + // 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); @@ -171,11 +173,12 @@ HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FL * @param hmemspi - указатель на хендл внешней памяти. * @param WriteInit - указатель на структуру, определяющую участок памяти для записи. * @param Timeout - время, за которое должно быть осуществлено чтение. + * @param WaitForEnd - ожидание, пока память не выполненит операцию. * @return HAL status. * @note Позволяет перепрограммировать участок памяти. Можно записывать несколько страниц. * Данные в сектора участка, но за пределами участка не сохраняются. */ -HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_WriteInitTypeDef *WriteInit, uint32_t Timeout) +HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_WriteInitTypeDef *WriteInit, uint32_t Timeout, uint8_t WaitForEnd) { uint32_t tickstart = HAL_GetTick(); uint32_t timeoutcnt = Timeout; @@ -187,8 +190,8 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write return HAL_TIMEOUT; // return timeout error // ERASE FLASH - MEMSPI_Status = MEMSPI_FLASH_Erase(hmemspi, WriteInit->Sector_Address, WriteInit->Sector_Size, Timeout); - if(MEMSPI_Status != HAL_OK) + 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 return MEMSPI_Status; // WRITE FLASH WITH SAVING PREVIOUS DATA @@ -211,7 +214,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write // PROGRAM FLASH WITH NEW DATA // program data to flash - MEMSPI_Status = MEMSPI_FLASH_Program(hmemspi, WriteInit->Sector_Address, writebuff, WriteInit->Sector_Size, Timeout); + MEMSPI_Status = MEMSPI_FLASH_Program(hmemspi, WriteInit->Sector_Address, writebuff, WriteInit->Sector_Size, Timeout, 1); if(MEMSPI_Status != HAL_OK) return MEMSPI_Status; } @@ -223,7 +226,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write Timeout -= timeoutcnt; tickstart += timeoutcnt; // program data to flash - MEMSPI_Status = MEMSPI_FLASH_Program(hmemspi, WriteInit->Sector_Address, writebuff, WriteInit->Sector_Size, Timeout); + MEMSPI_Status = MEMSPI_FLASH_Program(hmemspi, WriteInit->Sector_Address, writebuff, WriteInit->Sector_Size, Timeout, WaitForEnd); if(MEMSPI_Status != HAL_OK) return MEMSPI_Status; } @@ -237,10 +240,11 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write * @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) +HAL_StatusTypeDef MEMSPI_FLASH_Program(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; @@ -261,8 +265,8 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t F hmemspi->hNextAddr = FLASH_Address; // address would increase automatically in this variable for(int i = 0; i < lastpage - firstpage; i++) { - MEMSPI_Status = MEMSPI_FLASH_Program_Page(hmemspi, hmemspi->hNextAddr, &pData[bytecnt], currentpage_size, &Timeout, &tickstart); // programm page - if(MEMSPI_Status != HAL_OK) + 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 return MEMSPI_Status; // note for multiple page program: first we program rest of the first page, @@ -272,8 +276,8 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t F currentpage_size = MEMSPI_PAGE_SIZE; } - // PROGRAM LAST PAGE - MEMSPI_Status = MEMSPI_FLASH_Program_Page(hmemspi, hmemspi->hNextAddr, &pData[bytecnt], lastpage_size, &Timeout, &tickstart); // programm 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; @@ -287,11 +291,12 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t F * @param FLASH_Address - адресс где надо данные стереть. * @param Size - сколько байтов стереть. * @param Timeout - время, за которое должно быть осуществлена очистка. + * @param WaitForEnd - ожидание, пока память не выполненит операцию. * @return HAL status. * @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) +HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd) { uint32_t tickstart = HAL_GetTick(); HAL_StatusTypeDef MEMSPI_Status; @@ -303,7 +308,7 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA for(int i = 0; i <= (lastsector - firstsector); i++) { - MEMSPI_Status = MEMSPI_FLASH_Erase_Sector(hmemspi, FLASH_Address, &Timeout, &tickstart); // programm page + MEMSPI_Status = MEMSPI_FLASH_Erase_Sector(hmemspi, FLASH_Address, &Timeout, &tickstart, WaitForEnd); // programm page if(MEMSPI_Status != HAL_OK) return MEMSPI_Status; FLASH_Address += MEMSPI_SECTOR_SIZE; @@ -317,11 +322,12 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA * @param FLASH_Address - адресс где надо данные стереть. * @param Timeout - время, за которое должно быть осуществлена очистка. * @param tickstart - время, относительно которого надо отсчитывать таймаут. + * @param WaitForEnd - ожидание, пока память не выполненит операцию. * @return HAL status. * @note При Timeout = 0, функция не будет ожидать окончания очистки (выставления в 0 флагов BUSY и WEL) * @note Микросхема вроде сама высчитывает какой сектор ерейзнуть, в соответствии с заданным адресом. */ -HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t *Timeout, uint32_t *tickstart) +HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd) { HAL_StatusTypeDef MEMSPI_Status; // enable writting and waiting for unbusy @@ -333,8 +339,8 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint3 if(MEMSPI_Status != HAL_OK) return MEMSPI_Status; - // waiting for ending of erasing - if(Timeout) // if timeout isn zero - wait it. + // waiting for ending of erasing if need + if(WaitForEnd) if(MEMSPI_WaitOnFlagUntilTimeout(hmemspi, MEMSPI_SR_WEL|MEMSPI_SR_BUSY, 0, Timeout, tickstart) != HAL_OK) // if erase isnt done (MEMSPI busy and WEL bit isnt in reset state) return HAL_TIMEOUT; // return timeout because erasing instruction accepted, but arent done // note: if timeout == 0, erasing wouldnt be checking for ending (check busy flag) @@ -350,11 +356,12 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint3 * @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) +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) { HAL_StatusTypeDef MEMSPI_Status; // enable writting and waiting for unbusy @@ -370,9 +377,10 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program_Page(MEMSPI_HandleTypeDef *hmemspi, uint3 if(MEMSPI_Status != HAL_OK) return MEMSPI_Status; - // waiting for ending of writting - 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; + // 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); diff --git a/memory_spi/memory_spi.h b/memory_spi/memory_spi.h index 59f70a2..edffffb 100644 --- a/memory_spi/memory_spi.h +++ b/memory_spi/memory_spi.h @@ -161,21 +161,23 @@ HAL_StatusTypeDef MEMSPI_Read_Memory(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA * @param pData - откуда брать данные для записи в EEPROM. * @param Size - сколько байтов записать. * @param Timeout - время, за которое должно быть осуществлено чтение. + * @param WaitForEnd - ожидание, пока память не выполненит операцию. * @return HAL status. * @note Включает в себя проверку на доступность памяти (флаг BUSY) */ -HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef MEMSPI_EEPROM_Write(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd); /** * @brief Write external FLASH. * @param hmemspi - указатель на хендл внешней памяти. * @param WriteInit - указатель на структуру, определяющую участок памяти для записи. * @param Timeout - время, за которое должно быть осуществлено чтение. + * @param WaitForEnd - ожидание, пока память не выполненит операцию. * @return HAL status. * @note Позволяет перепрограммировать участок памяти. Можно записывать несколько страниц. * Данные в сектора участка, но за пределами участка не сохраняются. */ -HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_WriteInitTypeDef *WriteInit, uint32_t Timeout); +HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_WriteInitTypeDef *WriteInit, uint32_t Timeout, uint8_t WaitForEnd); /** * @brief Program external FLASH. @@ -184,10 +186,11 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write * @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); +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 Erase external FLASH. @@ -195,11 +198,12 @@ HAL_StatusTypeDef MEMSPI_FLASH_Program(MEMSPI_HandleTypeDef *hmemspi, uint32_t F * @param FLASH_Address - адресс где надо данные стереть. * @param Size - сколько байтов стереть. * @param Timeout - время, за которое должно быть осуществлена очистка. + * @param WaitForEnd - ожидание, пока память не выполненит операцию. * @return HAL status. * @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); +HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint16_t Size, uint32_t Timeout, uint8_t WaitForEnd); ///////////////////////---FUNCTIONS FOR USER---////////////////////// ///////////////////////////////////////////////////////////////////// @@ -210,11 +214,12 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA * @param FLASH_Address - адресс где надо данные стереть. * @param Timeout - время, за которое должно быть осуществлена очистка. * @param tickstart - время, относительно которого надо отсчитывать таймаут. + * @param WaitForEnd - ожидание, пока память не выполненит операцию. * @return HAL status. * @note При Timeout = 0, функция не будет ожидать окончания очистки (выставления в 0 флагов BUSY и WEL) * @note Микросхема вроде сама высчитывает какой сектор ерейзнуть, в соответствии с заданным адресом. */ -HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t *Timeout, uint32_t *tickstart); +HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint32_t *Timeout, uint32_t *tickstart, uint8_t WaitForEnd); /** * @brief Program page in external FLASH. @@ -224,11 +229,12 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase_Sector(MEMSPI_HandleTypeDef *hmemspi, uint3 * @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); +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); /** * @brief Setting WEL bit until it setted or until timeout.