/*
 * flash_page.c
 *
 *  Created on: May 13, 2021
 *      Author: xavie
 */

#include "flash_page.h"
#include "string.h"
#include "stdio.h"
#include "main.h"

static uint32_t GetPage(uint32_t Address)
{
  for (int indx=0; indx < 512; indx++)
  {
	  if((Address < (0x08000000 + (FLASH_PAGE_SIZE *(indx+1))) ) && (Address >= (0x08000000 + FLASH_PAGE_SIZE*indx)))
	  {
		  return ( Address < 0x08080000 ? indx : indx - 256 );
	  }
  }

  return -1;
}

uint32_t Flash_Write_Data (uint32_t StartPageAddress, __IO uint64_t * DATA_64, uint16_t bsize)
{
	uint32_t ret = 0;
	static FLASH_EraseInitTypeDef EraseInitStruct;
	uint32_t PAGEError;
	int sofar=0;

	/* Unlock the Flash to enable the flash control register access *************/
	HAL_FLASH_Unlock();
	__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
	                           FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR);

	/* Erase the user Flash area*/

	uint32_t StartPage = GetPage(StartPageAddress);
	uint32_t EndPageAdress = StartPageAddress + bsize;
	uint32_t EndPage = GetPage(EndPageAdress);

	/* Fill EraseInit structure*/
	EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
	EraseInitStruct.Banks		= (StartPageAddress < 0x08080000 ? FLASH_BANK_1 : FLASH_BANK_2);
	EraseInitStruct.Page		= StartPage;
	EraseInitStruct.NbPages     = (EndPage - StartPage) +1;

	if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
	{
		/*Error occurred while page erase.*/
		ret = HAL_FLASH_GetError ();
	}

	/* Program the user Flash area word by word*/
	bsize = ( bsize / sizeof( uint64_t ))+(( bsize % sizeof( uint64_t ))!=0);

	while ( sofar < bsize && ret == HAL_OK )
	{
		if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, StartPageAddress, DATA_64[sofar]) == HAL_OK)
		{
			StartPageAddress += 8;  // use StartPageAddress += 2 for half word and 8 for double word
			sofar++;
		}
		else
		{
			/* Error occurred while writing data in Flash memory*/
			ret = HAL_FLASH_GetError ();
		}
	}

	/* Lock the Flash to disable the flash control register access (recommended
	   to protect the FLASH memory against possible unwanted operation) *********/
	HAL_FLASH_Lock();

	return ret;
}

void Flash_Read_Data (uint32_t StartPageAddress, __IO uint32_t * DATA_32, uint16_t wsize)
{
	while (1)
	{
		*DATA_32 = *(__IO uint32_t *)StartPageAddress;
		StartPageAddress += 4;
		DATA_32++;
		if (!(wsize--)) break;
	}
}


