//----------------------------------------------------------------------------
//
//
//----------------------------------------------------------------------------


//---Includes-----------------------------------------------------------------


#include <biwak/option_bytes.hpp>
#include <HALWrapper/stm32_flash.h>
#include <stdio.h>   // printf
#include <unistd.h>   // usleep


//---Declarations-------------------------------------------------------------


COptionBytes::COptionBytes( )
{
}


COptionBytes::~COptionBytes()
{
}

#if defined OB_DATA_ADDRESS_DATA0

uint8_t COptionBytes::readByte(int address)
{
   static_assert( OB_DATA_ADDRESS_DATA1 == OB_DATA_ADDRESS_DATA0 + 2 );
   return( reinterpret_cast<uint8_t*>(OB_DATA_ADDRESS_DATA0 ) [address*2] );
}


int COptionBytes::writeByte(int adress, uint8_t value)
{
   int sta;
   FLASH_OBProgramInitTypeDef OBInit; // programming option structure
   
   static_assert( OB_DATA_ADDRESS_DATA1 == OB_DATA_ADDRESS_DATA0 + 2 );
   OBInit.DATAAddress = OB_DATA_ADDRESS_DATA0 + (adress*2); // address of type FLASHEx_OB_Data_Address
   OBInit.DATAData = value; // mode value to be saved
   OBInit.OptionType = OPTIONBYTE_DATA; // of type FLASHEx_OB_Type
   
   // Those may return error e.g. if it already was unlocked
   HAL_FLASH_Unlock();
   HAL_FLASH_OB_Unlock();
   
   if( !adress )
   {
      sta=HAL_FLASHEx_OBErase();
   }
   
   ( sta = HAL_FLASHEx_OBProgram(&OBInit) ) ||
   ( sta = HAL_FLASH_Lock() ) ||
   ( sta = HAL_FLASH_OB_Lock() );

   return(sta);
}

#endif

int COptionBytes::count()
{
   #if defined ( OB_DATA_ADDRESS_DATA1 )
      return(2);
   #elif defined ( OB_DATA_ADDRESS_DATA0 )
      return(1);
   #else
      return(0);
   #endif
}


//----------------------------------------------------------------------------
