
//[2009.07.07.화][생성!!!]{---------------------------------------------------
//맷돌에 사용된 STM32F103 의 Flash 에 접근하기 위한 함수들을 정의한다.
//모두 [직렬버스] 로 직접 접근하는 방법을 사용한다.
//속도는 느리지만 가장 제어하기 쉽고, 모든 것을 IDE 쪽에서 제어 할수 있으므로
//보다 관리가 쉬워진다.
//}---------------------------------------------------------------------------


#include <vcl.h>
#pragma hdrstop


#include  "ide_library.h"

#include  "flash.h"

#include  "combus.h"

#include  "STM32F103C8T6.h"


bool __fastcall Flash_Key(void)
{
  //[2009.07.07.화][생성!!!]{------------------------------
  //Flash 를 쓰기 위하여 일단 [보호해제] 를 수행해야 한다.
  //}------------------------------------------------------

  //[VAR]
  //{
      unsigned int  flash_keyr;

  //}

  //[초기화]
  //{
      flash_keyr = 0;

  //}

  //KEY1 기록.
  flash_keyr = 0x45670123;
  if(ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_KEYR, (unsigned char *)(&flash_keyr)) != true) return(false);

  //KEY2 기록.
  flash_keyr = 0xcdef89ab;
  if(ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_KEYR, (unsigned char *)(&flash_keyr)) != true) return(false);

  return(true);

}

bool __fastcall Flash_WriteBoho(void)
{
  //[2009.12.24.목][생성!!!]{----------------------------------------------------
  //Flash 기록하지 못하도록 다른 키값을 넣어준다.
  //일시적으로 Flash 에 임의 기록을 할수 없는 상태가 된다.
  //
  //Flash 에 쓰기를 위하여 Flash_Key() 함수로 쓰기 상태를 만들고 모든 쓰기과정이
  //끝난뒤에는 반드시 이 함수로 [보호상태] 로 만들어 놓아야 한다.
  //이는 VMOS 와 사용자 [가상기계] 의 변형을 막기 위한 것이다.
  //}----------------------------------------------------------------------------

  //[VAR]
  //{
      DTU4  temp4;

  //}

  //[FLASH_CR 읽기]
  //{
      //<FLASH_CR> 값을 읽어 들인다.
      if(ComBus_Read(d_CB_TS_T, d_CB_AK_M, 2, FLASH_CR, (unsigned char *)(&temp4)) != true) return(false);

  //}

  //[FLASH_CR 쓰기]
  //{
      //[!]{---------------------------------------------------------------------------------------
      //<FLASH_CR.7 : 1> 을 하면 Flash 에 임의 기록을 할수 없는 보호 상태가 된다.
      //이는 Flash_Key() 함수로 키를 주어야만 해제된다(SW 적으로는 설정만 되고 해제되지는 않는다).
      //}------------------------------------------------------------------------------------------

      temp4 |= (1 << 7);
      if(ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_CR, (unsigned char *)(&temp4)) != true) return(false);

  //}

  return(true);

}

void __fastcall Flash_Write(DTU4  pAdr,
                            DTU2  p16Bit)
{
  //[2009.07.07.화][생성!!!]{-----------------------------------------------------------
  //Flash 의 지정 주소에 16Bit 를 기록한다.
  //STM32FXXX 계열은 1Address:16Bit 씩 기록해야하며,
  //이 함수는 이미 해당 Page 의 Lock 가 제거되고, Erase 된 상태인 경우에 사용해야 한다.
  //아주 잘 동작 된다.
  //}-----------------------------------------------------------------------------------

  //[VAR]
  //{
      unsigned int  flash_cr, flash_sr;

  //}
  
  //[초기화]
  //{
      flash_cr = 0;
      flash_sr = 0;
  
  //}
  
  //[Flash 프로그램 허가]
  //{
      //FLASH_CR.PG(0) 비트를 1 로하여 Flash 에 기록을 허가한다.
      flash_cr = (1 << 0);
      ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_CR, (unsigned char *)(&flash_cr));
      
  //}    
  
  //[값 기록]
  //{
      //일반적인 방법으로 FLash 의 지정수소에 그냥 간단하게 기록하면 된다.
      ComBus_Write(d_CB_TS_T, d_CB_AK_M, 1, pAdr, (unsigned char *)(&p16Bit));
      
  //}    
  
  //[완료 확인]
  //{
      //FLASH_SR.BSY(0) 비트가 0 이면 완료된 것이다.
      do 
      { 
        ComBus_Read(d_CB_TS_T, d_CB_AK_M, 2, FLASH_SR, (unsigned char *)(&flash_sr));
      
      }
      while(flash_sr & (1 << 0));
      
  //}

  return;

}

void __fastcall Flash_Erase(void)
{
  //[2009.07.07.화][생성!!!]{--------------------------------------------------
  //<d_CodeBase_VMOS> 부터 Flash 끝까지 전부 지운다.
  //실제 VMOS 가 존재하는 0x1000 부터 끝까지만 전부 지운다.
  //따라서, 전체를 한꺼번에 지우면 안되고, PAGE 단위로 1 Kbyte 씩 지워야 한다.
  //현재 사용되고 있는 STM32F103 은 1KByte/1Page 이다.
  //총 64Kbyte 의 Flash 를 가지고 있으므로 BaseVM 을 제외하고 총 60개의
  //페이지를 지우면 된다.
  //
  //만드시 먼저, Flash_보호해제() 함수로 보호를 해제한 상태여야 한다.
  //}--------------------------------------------------------------------------
  
  //[VAR]
  //{
      unsigned int  flash_cr, flash_ar, flash_sr;
      int           i;
      
  //}
  
  //[초기화]
  //{
      flash_cr = 0; 
      flash_ar = 0;
      flash_sr = 0;
  
  //}

  //[Flash 페이지 지우기 허가]
  //{
      //FLASH_CR.PER(1) 비트를 1 로하여 Flash 페이지 지우기를 허가한다.
      flash_cr = (1 << 1);
      ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_CR, (unsigned char *)(&flash_cr));

  //}

  //[60개 페이지 지우기]
  //{
      //BaseVm 이 존재하는 처음 4개 페이지다음부터 끝까지 60 개의 페이지를 모두 지운다.
      for(i = 0; i < 60; i++)
      {
        //[페이지 주소 기록]
        //{
            flash_ar = //BaseVM 다음 페이지부터 시작한다.
                       0x1000 +
                       //페이지당 1KByte 크기를 갖는다.
                       0x400*i;

            ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_AR, (unsigned char *)(&flash_ar));

        //}

        //[지우기 시작]
        //{
            //FLASH_CR.STRT(6) 비트를 1 로하여 Flash 페이지를 지운다.
            flash_cr |= (1 << 6);
            ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_CR, (unsigned char *)(&flash_cr));

        //}

        //[완료 확인]
        //{
            //FLASH_SR.BSY(0) 비트가 0 이면 완료된 것이다.
            do
            {
              ComBus_Read(d_CB_TS_T, d_CB_AK_M, 2, FLASH_SR, (unsigned char *)(&flash_sr));

            }
            while(flash_sr & (1 << 0));

        //}

      }

  //}

  //여기까지 BaseVM 을 제외한 60개의 모든 페이지가 지워졌다.

  return;

}

void __fastcall Flash_PageErase(//페이지의 [기반주소].
                                DTU4  pPageBaseAdr)
{
  //[2009.07.15.수][생성!!!]{--------------------------------------------------
  //STM32F103 은 1KByte 단위 페이지를 가지고 있는데, 이 페이지의 [기반주소] 를
  //전달 받아서 해당 페이지만 삭제한다.
  //
  //만드시 먼저, Flash_보호해제() 함수로 보호를 해제한 상태여야 한다.
  //}--------------------------------------------------------------------------

  //[VAR]
  //{
      unsigned int  flash_cr, flash_ar, flash_sr;
      int           i;

  //}

  //[초기화]
  //{
      flash_cr = 0;
      flash_ar = 0;
      flash_sr = 0;
  
  //}

  //[Flash 페이지 지우기 허가]
  //{
      //FLASH_CR.PER(1) 비트를 1 로하여 Flash 페이지 지우기를 허가한다.
      flash_cr = (1 << 1);
      ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_CR, (unsigned char *)(&flash_cr));

  //}

  //[지정 페이지 지우기]
  //{
      //BaseVm 이 존재하는 처음 4개 페이지다음부터 끝까지 60 개의 페이지를 모두 지운다.

      //[페이지 주소 기록]
      //{
          //삭제할 페이지의 [시작주소] 를 기록한다.
          //1KByte 단위로 정리한다.
          flash_ar = pPageBaseAdr & (~((DTU4)0x3ff));

          ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_AR, (unsigned char *)(&flash_ar));

      //}

      //[지우기 시작]
      //{
          //FLASH_CR.STRT(6) 비트를 1 로하여 Flash 페이지를 지운다.
          flash_cr |= (1 << 6);
          ComBus_Write(d_CB_TS_T, d_CB_AK_M, 2, FLASH_CR, (unsigned char *)(&flash_cr));

      //}

      //[완료 확인]
      //{
          //FLASH_SR.BSY(0) 비트가 0 이면 완료된 것이다.
          do
          {
            ComBus_Read(d_CB_TS_T, d_CB_AK_M, 2, FLASH_SR, (unsigned char *)(&flash_sr));

          }
          while(flash_sr & (1 << 0));

      //}

  //}

  return;

}



