
//[2011.10.20.목][생성!!!]{----------------------
//원래 <main.c> 에 존재하던 것을 별도의 문서로 분리한다.
//}---------------------------------------------


#include "함수묶음.h"

#include "일반함수.h"

#include "main.h"
#include "GUI\GUI.h"


void 기준경로얻기(char  *r기준경로)
{
  //[2011.10.18.화][생성!!!]{----------------------------------------------
  //[GVMS] 가 실행되는 기준경로 를 얻는다.
  //실제 배포판을 위한 것으로 원래는 <*.gvms> 가 실행되고 있는 위치가 맞으나
  //[맷돌-통합개발환경] 에서 실행하는 경우는 <*.gvms> 가 항상 <build> 안에서 실행되므로
  //이 경우는 <build> 밖으로 설정해 주어야 한다.
  //}---------------------------------------------------------------------

  //[VAR]
  //{
      char  문자열[256];

  //}

  //[<*.gvms> 실행 경로]
  //{
      //<*.gvms> 실행 경로 얻기.
      _Ide_가상기계_실행경로_(r기준경로);

  //}

  //[<build> 폴더 안에 있나?]
  //{
      //[!]{-------------------------------------------------------------------
      //배포판을 기준으로 해야 하므로 최종 폴더이름이 "build" 인 경우는 이 폴더밖으로 수정한다.
      //}----------------------------------------------------------------------

      _FileStr_최종폴더이름얻기_(r기준경로, 문자열);

      //대/소문자 구분없이 검사.
      if(_Str_일치확인_(문자열, "build", false) == true)
      {
        //[!]{---------------------------------------------------------
        //"...\build\" 의 상태이므로 'b' 위치에 '\0' 을 넣어 문자열을 마무리 지어
        //"...\" 로 만든다.
        //}------------------------------------------------------------

        //"build\" 길이------------------v
        r기준경로[_Str_길이얻기_(r기준경로) - 6] = '\0';

      }

  //}

}

void Ide_AVR설정정보를_GUI에_반영(struct AVR설정정보  *pAVR설정정보)
{
  //[2011.10.21.금][생성!!!]{------------
  //[AVR설정정보] 의 내용대로 GUI 를 설정한다.
  //}-----------------------------------

  //[VAR]
  //{
      int  i;

  //}

  //[GUI/전역변수]{------
  struct 전역변수  *gv;
  struct GUI     *gui;
  전역변수_위치얻기(&gv);
  GUI_위치얻기(&gui);
  //}------------------

  //[설정보안]
  //{
      for(i = 7; i >= 0; i--)
      {
        //[Chk_설정보안비트]
        //{
            _GCheckButton_확인_(gui->Chk_설정보안비트[i], pAVR설정정보->보안설정[i].사용유무, d_쓰기);

            //<고정유뮤> 는 반대로 적용--------------------v
            _GCheckButton_유효_(gui->Chk_설정보안비트[i], !(pAVR설정정보->보안설정[i].고정유무), d_쓰기);

        //}

        //[Lb_설정보안비트]
        //{
            _GLabel_제목_(gui->Lb_설정보안비트[i], pAVR설정정보->보안설정[i].이름, d_쓰기);

        //}

      }

      //[설정정보 존재 확인]
      //{
          //[2011.11.08.화][추가!!!]{-----------------------------------------
          //모든 [이름] 이 "-" 인 경우는 AVR 자체에 이 [설정정보비트] 가 없는 것으로 보고
          //해당 [쓰기/읽기 버튼] 을 무효화 한다.
          //}----------------------------------------------------------------

          if(Ide_설정비트정보_존재확인(pAVR설정정보->보안설정) == true)
          {
            _GButton_유효_(gui->Btn_설정보안_쓰기, true, d_쓰기);
            _GButton_유효_(gui->Btn_설정보안_읽기, true, d_쓰기);

            _GButton_제목_(gui->Btn_설정보안_쓰기, "쓰기", d_쓰기);
            _GButton_제목_(gui->Btn_설정보안_읽기, "읽기", d_쓰기);

          }
          else
          {
            _GButton_유효_(gui->Btn_설정보안_쓰기, false, d_쓰기);
            _GButton_유효_(gui->Btn_설정보안_읽기, false, d_쓰기);

            _GButton_제목_(gui->Btn_설정보안_쓰기, "-", d_쓰기);
            _GButton_제목_(gui->Btn_설정보안_읽기, "-", d_쓰기);

          }

      //}

  //}

  //[설정확장]
  //{
      for(i = 7; i >= 0; i--)
      {
        //[Chk_설정확장비트]
        //{
            _GCheckButton_확인_(gui->Chk_설정확장비트[i], pAVR설정정보->확장설정[i].사용유무, d_쓰기);

            //<고정유뮤> 는 반대로 적용--------------------v
            _GCheckButton_유효_(gui->Chk_설정확장비트[i], !(pAVR설정정보->확장설정[i].고정유무), d_쓰기);

        //}

        //[Lb_설정확장비트]
        //{
            _GLabel_제목_(gui->Lb_설정확장비트[i], pAVR설정정보->확장설정[i].이름, d_쓰기);

        //}

      }

      //[설정정보 존재 확인]
      //{
          //[2011.11.08.화][추가!!!]{-----------------------------------------
          //모든 [이름] 이 "-" 인 경우는 AVR 자체에 이 [설정정보비트] 가 없는 것으로 보고
          //해당 [쓰기/읽기 버튼] 을 무효화 한다.
          //}----------------------------------------------------------------

          if(Ide_설정비트정보_존재확인(pAVR설정정보->확장설정) == true)
          {
            _GButton_유효_(gui->Btn_설정확장_쓰기, true, d_쓰기);
            _GButton_유효_(gui->Btn_설정확장_읽기, true, d_쓰기);

            _GButton_제목_(gui->Btn_설정확장_쓰기, "쓰기", d_쓰기);
            _GButton_제목_(gui->Btn_설정확장_읽기, "읽기", d_쓰기);

          }
          else
          {
            _GButton_유효_(gui->Btn_설정확장_쓰기, false, d_쓰기);
            _GButton_유효_(gui->Btn_설정확장_읽기, false, d_쓰기);

            _GButton_제목_(gui->Btn_설정확장_쓰기, "-", d_쓰기);
            _GButton_제목_(gui->Btn_설정확장_읽기, "-", d_쓰기);

          }

      //}

  //}

  //[설정상위]
  //{
      for(i = 7; i >= 0; i--)
      {
        //[Chk_설정상위비트]
        //{
            _GCheckButton_확인_(gui->Chk_설정상위비트[i], pAVR설정정보->상위설정[i].사용유무, d_쓰기);

            //<고정유뮤> 는 반대로 적용--------------------v
            _GCheckButton_유효_(gui->Chk_설정상위비트[i], !(pAVR설정정보->상위설정[i].고정유무), d_쓰기);

        //}

        //[Lb_설정상위비트]
        //{
            _GLabel_제목_(gui->Lb_설정상위비트[i], pAVR설정정보->상위설정[i].이름, d_쓰기);

        //}

      }

      //[설정정보 존재 확인]
      //{
          //[2011.11.08.화][추가!!!]{-----------------------------------------
          //모든 [이름] 이 "-" 인 경우는 AVR 자체에 이 [설정정보비트] 가 없는 것으로 보고
          //해당 [쓰기/읽기 버튼] 을 무효화 한다.
          //}----------------------------------------------------------------

          if(Ide_설정비트정보_존재확인(pAVR설정정보->상위설정) == true)
          {
            _GButton_유효_(gui->Btn_설정상위_쓰기, true, d_쓰기);
            _GButton_유효_(gui->Btn_설정상위_읽기, true, d_쓰기);

            _GButton_제목_(gui->Btn_설정상위_쓰기, "쓰기", d_쓰기);
            _GButton_제목_(gui->Btn_설정상위_읽기, "읽기", d_쓰기);

          }
          else
          {
            _GButton_유효_(gui->Btn_설정상위_쓰기, false, d_쓰기);
            _GButton_유효_(gui->Btn_설정상위_읽기, false, d_쓰기);

            _GButton_제목_(gui->Btn_설정상위_쓰기, "-", d_쓰기);
            _GButton_제목_(gui->Btn_설정상위_읽기, "-", d_쓰기);

          }

      //}

  //}

  //[설정하위]
  //{
      for(i = 7; i >= 0; i--)
      {
        //[Chk_설정하위비트]
        //{
            _GCheckButton_확인_(gui->Chk_설정하위비트[i], pAVR설정정보->하위설정[i].사용유무, d_쓰기);

            //<고정유뮤> 는 반대로 적용--------------------v
            _GCheckButton_유효_(gui->Chk_설정하위비트[i], !(pAVR설정정보->하위설정[i].고정유무), d_쓰기);

        //}

        //[Lb_설정하위비트]
        //{
            _GLabel_제목_(gui->Lb_설정하위비트[i], pAVR설정정보->하위설정[i].이름, d_쓰기);

        //}

      }

      //[설정정보 존재 확인]
      //{
          //[2011.11.08.화][추가!!!]{-----------------------------------------
          //모든 [이름] 이 "-" 인 경우는 AVR 자체에 이 [설정정보비트] 가 없는 것으로 보고
          //해당 [쓰기/읽기 버튼] 을 무효화 한다.
          //}----------------------------------------------------------------

          if(Ide_설정비트정보_존재확인(pAVR설정정보->하위설정) == true)
          {
            _GButton_유효_(gui->Btn_설정하위_쓰기, true, d_쓰기);
            _GButton_유효_(gui->Btn_설정하위_읽기, true, d_쓰기);

            _GButton_제목_(gui->Btn_설정하위_쓰기, "쓰기", d_쓰기);
            _GButton_제목_(gui->Btn_설정하위_읽기, "읽기", d_쓰기);

          }
          else
          {
            _GButton_유효_(gui->Btn_설정하위_쓰기, false, d_쓰기);
            _GButton_유효_(gui->Btn_설정하위_읽기, false, d_쓰기);

            _GButton_제목_(gui->Btn_설정하위_쓰기, "-", d_쓰기);
            _GButton_제목_(gui->Btn_설정하위_읽기, "-", d_쓰기);

          }

      //}

  //}

}

void Ide_GUI설정을_AVR설정정보에_정리(struct AVR설정정보  *rAVR설정정보)
{
  //[2011.10.21.금][생성!!!]-----------------------
  //현재 GUI 상의 설정을 그대로 [AVR설정정보] 에 저장한다.
  //}---------------------------------------------

  //[VAR]
  //{
      int  i;

  //}

  //[GUI/전역변수]{------
  struct 전역변수  *gv;
  struct GUI     *gui;
  전역변수_위치얻기(&gv);
  GUI_위치얻기(&gui);
  //}------------------

  //[설정보안]
  //{
      for(i = 7; i >= 0; i--)
      {
        //[Chk_설정보안비트]
        //{
            rAVR설정정보->보안설정[i].사용유무 = _GCheckButton_확인_(gui->Chk_설정보안비트[i], 0, d_읽기);

            //<고정유뮤> 는 반대로 적용---------v
            rAVR설정정보->보안설정[i].고정유무 = !_GCheckButton_유효_(gui->Chk_설정보안비트[i], 0, d_읽기);

        //}

        //[Lb_설정보안비트]
        //{
            _GLabel_제목_(gui->Lb_설정보안비트[i], rAVR설정정보->보안설정[i].이름, d_읽기);

        //}

      }

  //}

  //[설정확장]
  //{
      for(i = 7; i >= 0; i--)
      {
        //[Chk_설정확장비트]
        //{
            rAVR설정정보->확장설정[i].사용유무 = _GCheckButton_확인_(gui->Chk_설정확장비트[i], 0, d_읽기);

            //<고정유뮤> 는 반대로 적용---------v
            rAVR설정정보->확장설정[i].고정유무 = !_GCheckButton_유효_(gui->Chk_설정확장비트[i], 0, d_읽기);

        //}

        //[Lb_설정확장비트]
        //{
            _GLabel_제목_(gui->Lb_설정확장비트[i], rAVR설정정보->확장설정[i].이름, d_읽기);

        //}

      }

  //}

  //[설정상위]
  //{
      for(i = 7; i >= 0; i--)
      {
        //[Chk_설정상위비트]
        //{
            rAVR설정정보->상위설정[i].사용유무 = _GCheckButton_확인_(gui->Chk_설정상위비트[i], 0, d_읽기);

            //<고정유뮤> 는 반대로 적용---------v
            rAVR설정정보->상위설정[i].고정유무 = !_GCheckButton_유효_(gui->Chk_설정상위비트[i], 0, d_읽기);

        //}

        //[Lb_설정상위비트]
        //{
            _GLabel_제목_(gui->Lb_설정상위비트[i], rAVR설정정보->상위설정[i].이름, d_읽기);

        //}

      }

  //}

  //[설정하위]
  //{
      for(i = 7; i >= 0; i--)
      {
        //[Chk_설정하위비트]
        //{
            rAVR설정정보->하위설정[i].사용유무 = _GCheckButton_확인_(gui->Chk_설정하위비트[i], 0, d_읽기);

            //<고정유뮤> 는 반대로 적용---------v
            rAVR설정정보->하위설정[i].고정유무 = !_GCheckButton_유효_(gui->Chk_설정하위비트[i], 0, d_읽기);

        //}

        //[Lb_설정하위비트]
        //{
            _GLabel_제목_(gui->Lb_설정하위비트[i], rAVR설정정보->하위설정[i].이름, d_읽기);

        //}

      }

  //}

}

void Ide_Flash_문자열로변환(//AVR Flash 는 [1주소:2바이트].
                         unsigned short  *p저장소,
                         //16 배수로 지정(한 행에 16 개의 자료가 위치).
                         unsigned int     p처리시작주소,
                         //16 배수로 지정(한 행에 16 개의 자료가 위치).
                         unsigned int     p처리주소크기,
                         //행의 맨 앞에 [주소] 를 붙여줄지 결정(true:붙이기).
                         bool             p주소포함,
                         char            *r문자열)
{
  //[2011.11.03.목][생성!!!]{-----------------------------
  //저장소의 내용을 읽어 [AVR Flash] 에 맞게 문자열로 변환해 준다.
  //
  //AVR 은 [1주소:2바이트] 이므로 1 행에 16 개의 자료가 위치하도록
  //<p주소포함> 의 여부에 따라
  //"AAAAAAAA XXXX XXXX XXXX XXXX ..."
  //"XXXX XXXX XXXX XXXX ..."
  //의 형식으로 합성한다.
  //"AAAAAAAA" 는 주소.
  //}----------------------------------------------------

  //[VAR]
  //{
      int   i, j;

      //문자열 저장 위치.
      int   s;

  //}

  //[전처리]
  //{
      r문자열[0] = '\0';

      s = 0;

  //}

  //[합성]
  //{
      for(i = p처리시작주소; i < p처리주소크기; i += 16)
      {
        //[주소 추가]
        //{
            if(p주소포함 == true)
            {
              //행의 맨 앞에 [주소] "XXXXXXXX" 를 붙인다.
              _Conv_Long값_16진수표기_(i, 8, &(r문자열[s]));

              //"XXXXXXXX" 크기만큼 저장위치 이동.
              s += 8;

              //자료를 공백 한개로 구분.
              s += _Str_더하기_(&(r문자열[s]), ": ");

            }

        //}

        //한개 행을 처리.
        for(j = 0; j < 16; j++)
        {
          //[변환]
          //{
              _Conv_Long값_16진수표기_(p저장소[i + j], 4, &(r문자열[s]));

              //"xxxx" 크기만큼 저장위치 이동.
              s += 4;

          //}

          //자료를 공백 한개로 구분.
          s += _Str_더하기_(&(r문자열[s]), " ");

        }

        //행으로 만들기.
        s += _Str_더하기_(&(r문자열[s]), "\r\n");

      }

      //[맨뒤 CRLF 삭제]
      //{
          //<GList> 에 추가하는 경우는 빈행도 [빈항목] 으로 추가되므로 삭제한다.
          if(s > 2) { r문자열[s - 2] = '\0'; }

      //}

  //}

}

void Ide_EEprom_문자열로변환(unsigned char  *p저장소,
                          //16 배수로 지정(한 행에 16 개의 자료가 위치).
                          unsigned int    p처리시작주소,
                          //16 배수로 지정(한 행에 16 개의 자료가 위치).
                          unsigned int    p처리주소크기,
                          //행의 맨 앞에 [주소] 를 붙여줄지 결정(true:붙이기).
                          bool            p주소포함,
                          char           *r문자열)
{
  //[2011.11.03.목][생성!!!]{------------------------------
  //저장소의 내용을 읽어 [AVR EEprom] 에 맞게 문자열로 변환해 준다.
  //
  //<p주소포함> 의 여부에 따라
  //"AAAAAAAA XX XX XX XX ..."
  //"XX XX XX XX ..."
  //의 형식으로 합성한다.
  //"AAAAAAAA" 는 주소.
  //}-----------------------------------------------------

  //[VAR]
  //{
      int   i, j;

      //문자열 저장 위치.
      int   s;

  //}

  //[전처리]
  //{
      r문자열[0] = '\0';

      s = 0;

  //}

  //[합성]
  //{
      for(i = p처리시작주소; i < p처리주소크기; i += 16)
      {
        //[주소 추가]
        //{
            if(p주소포함 == true)
            {
              //행의 맨 앞에 [주소] "XXXXXXXX" 를 붙인다.
              _Conv_Long값_16진수표기_(i, 8, &(r문자열[s]));

              //"XXXXXXXX" 크기만큼 저장위치 이동.
              s += 8;

              //자료를 공백 한개로 구분.
              s += _Str_더하기_(&(r문자열[s]), ": ");

            }

        //}

        //한개 행을 처리.
        for(j = 0; j < 16; j++)
        {
          //[변환]
          //{
              _Conv_Long값_16진수표기_(p저장소[i + j], 2, &(r문자열[s]));

              //"xx" 크기만큼 저장위치 이동.
              s += 2;

          //}

          //자료를 공백 한개로 구분.
          s += _Str_더하기_(&(r문자열[s]), " ");

        }

        //행으로 만들기.
        s += _Str_더하기_(&(r문자열[s]), "\r\n");

      }

      //[맨뒤 CRLF 삭제]
      //{
          //<GList> 에 추가하는 경우는 빈행도 [빈항목] 으로 추가되므로 삭제한다.
          if(s > 2) { r문자열[s - 2] = '\0'; }

      //}

  //}

}

void Ide_Flash_저장소_초기화(//AVR Flash 는 [1주소:2바이트].
                          unsigned short  *p저장소)
{
  //[2011.11.04.금][생성!!!]{-----------------------------------------------
  //<전역변수:flash[]> 등 저장소를 현재 선택된 AVR 정보를 바탕으로 0xff 로 초기화 한다.
  //}----------------------------------------------------------------------

  //[VAR]
  //{
      int i;

  //}

  //[GUI/전역변수]{-----
  struct 전역변수  *gv;
  전역변수_위치얻기(&gv);
  //}-----------------

  for(i = 0; i < gv->AVR명세.flash크기/2; i++)
  {
    p저장소[i] = 0xffff;

  }

}

void Ide_EEprom_저장소_초기화(unsigned char  *p저장소)
{
  //[2011.11.04.금][생성!!!]{-------------------------------------------------
  //<전역변수:eeprom[]> 등 저장소를 현재 선택된 AVR 정보를 바탕으로 0x00 으로 초기화 한다.
  //
  //[2011.11.08.화][수정!!!]--------------------------------------------------
  //AVR 의 EEprom 이 지워진후 <0xff> 가 되므로 저장소의 초기화도 <0xff> 로 수정.
  //}------------------------------------------------------------------------

  //[VAR]
  //{
      int i;

  //}

  //[전역변수]{---------
  struct 전역변수  *gv;
  전역변수_위치얻기(&gv);
  //}-----------------

  for(i = 0; i < gv->AVR명세.eep크기; i++)
  {
    p저장소[i] = 0xff;

  }

}

bool Ide_Flash문서_다시열기(void)
{
  //[2011.11.05.토][생성!!!]{------------------------------------------------
  //이미 열려있는 <Flash> 에 기록할 문서를 다시 열어준다.
  //이는 Flash 에 기록시 <전역변수:flash[]> 에 정확한 내용을 담기위한것.
  //
  //이미 열여 있는 문서의 [경로이름확장자] 는 <Lb_Flash문서_경로:풍선도움말> 안에 들어있다.
  //}-----------------------------------------------------------------------

  //[VAR]
  //{
      char  경로이름확장자[512];

  //}

  //[GUI/전역변수]{------
  struct 전역변수  *gv;
  struct GUI     *gui;
  전역변수_위치얻기(&gv);
  GUI_위치얻기(&gui);
  //}------------------

  //[<경로이름확장자> 얻기]
  //{
      //<Lb_Flash문서_경로:풍선도움말> 안에 들어있다.
      _GLabel_풍선도움말문자열_(gui->Lb_Flash문서_경로, 경로이름확장자, d_읽기);

  //}

  //[처리할 것인가?]
  //{
      //처리할 내용이 없다면 여기서 종료.
      if(_Str_일치확인_(경로이름확장자, "기계닉스 첨단 대장간", false) == true) return(false);

  //}

  //[저장소 초기화]
  //{
      //<*.hex> 를 읽어들이기전 이전 내용이 남지 않도록 저장소를 초기화.
      Ide_Flash_저장소_초기화((unsigned short *)(gv->flash));

  //}

  //[<*.hex> 문서 읽기]
  //{
      //<*.hex> 문서를 [2진문서] 로 전용 저장소에 저장.
      _File_HexToBin_(경로이름확장자, gv->flash, NULL, NULL);

  //}

  return(true);

}

bool Ide_EEprom문서_다시열기(void)
{
  //[2011.11.05.토][생성!!!]{-------------------------------------------------
  //이미 열려있는 <EEprom> 에 기록할 문서를 다시 열어준다.
  //이는 EEprom 에 기록시 <전역변수:eeprom[]> 에 정확한 내용을 담기위한것.
  //
  //이미 열여 있는 문서의 [경로이름확장자] 는 <Lb_EEprom문서_경로:풍선도움말> 안에 들어있다.
  //}------------------------------------------------------------------------

  //[VAR]
  //{
      char  경로이름확장자[512];

  //}

  //[GUI/전역변수]{------
  struct 전역변수  *gv;
  struct GUI     *gui;
  전역변수_위치얻기(&gv);
  GUI_위치얻기(&gui);
  //}------------------

  //[<경로이름확장자> 얻기]
  //{
      //<Lb_EEprom문서_경로:풍선도움말> 안에 들어있다.
      _GLabel_풍선도움말문자열_(gui->Lb_EEprom문서_경로, 경로이름확장자, d_읽기);

  //}

  //[처리할 것인가?]
  //{
      //처리할 내용이 없다면 여기서 종료.
      if(_Str_일치확인_(경로이름확장자, "http://www.gigyenics.co.kr", false) == true) return(false);

  //}

  //[저장소 초기화]
  //{
      //<*.hex> 를 읽어들이기전 이전 내용이 남지 않도록 저장소를 초기화.
      Ide_EEprom_저장소_초기화(gv->eeprom);

  //}

  //[<*.hex> 문서 읽기]
  //{
      //<*.hex> 문서를 [2진문서] 로 전용 저장소에 저장.
      _File_HexToBin_(경로이름확장자, gv->eeprom, NULL, NULL);

  //}

  return(true);

}

bool Ide_통신개방확인(void)
{
  //[2011.11.06.일][생성!!!]{-----------------------------------------------
  //현재 [통신포트] 가 열려 있다면 <true> 를 반환한다.
  //이 함수는 다른 곳에서 ISP 를 위하여 [통신포트] 가 열려 있는지 확인하기 위하여 필요하다.
  //
  //<Btn_통신포트열기닫기> 의 [제목] 이 "닫기" 상태라면 열려 있는 것이다.
  //}----------------------------------------------------------------------

  //[VAR]
  //{
      char  문자열[512];

  //}

  //[GUI/전역변수]{---
  struct GUI  *gui;
  GUI_위치얻기(&gui);
  //}---------------

  //<Btn_통신포트열기닫기>제목 얻기.
  _GButton_제목_(gui->Btn_통신포트열기닫기, 문자열, d_읽기);

  //통신포트가 열려있나?
  if(_Str_일치확인_(문자열, "닫기", false) == true)
  {
    //이 경우는 현재 통신포트가 [열려] 있는 경우.
    return(true);

  }
  else
  {
    return(false);

  }

}

bool Ide_Flash_저장소_채워진_끝페이지번호_얻기(unsigned int  *r채워진끝페이지번호)
{
  //[2011.11.08.화][생성!!!]{---------------------------------------------
  //<전역변수:flash[]> 에서 <0xffff> 로 모두 채워져 있지 않은(기록할 자료가 들어있는)
  //가장 마지막 [페이지번호] 를 얻는다.
  //
  //실제는 맨뒤부터 검사하여 <0xffff> 가 아닌 자료가 발견된 [페이지번호] 가 해당.
  //
  //이 함수는 Flash 용량이 큰 AVR 의 경우, 전체를 다 기록하는 방식으로는 너무 시간이
  //많이 걸려서 유요한 부분 까지만 기록하기 위한 것.
  //
  //[주의!!!]-------------------------------------------------------------
  //AVR Flash 는 [1주소:2바이트] 로 돼 있으므로 <unsigned short *> 로 처리.
  //}--------------------------------------------------------------------

  //[VAR]
  //{
      int  i;

  //}

  //[전역변수]{---------
  struct 전역변수  *gv;
  전역변수_위치얻기(&gv);
  //}-----------------

  //맨 뒤부터 <0xffff> 가 아닌 자료 주소 찾기.
  for(i = (gv->AVR명세.flash크기/2 - 1); i >= 0; i--)
  {
    if(((unsigned short *)(gv->flash))[i] != 0xffff)
    {
      //이 [주소] 가 포함된 [페이지] 가 찾고자 하는 페이지.
      //[페이지크기] 는 1바이트 단위값이므로 </2> 로 사용.
      (*r채워진끝페이지번호) = i/(gv->AVR명세.flash페이지크기/2);

      //처리할 것이 있다.
      return(true);

    }

  }

  //여기까지 온것은 <전역변수:flash[]> 의 모든 영역이 <0xff> 인 것으로
  //처리할 것이 전혀 없는 것.
  return(false);

}

bool Ide_EEprom_저장소_채워진_끝단위묶음번호_얻기(unsigned int  *r채워진끝단위묶음번호)
{
  //[2011.11.08.화][생성!!!]{--------------------------------------------
  //<전역변수:eeprom[]> 에서 <0xff> 로 모두 채워져 있지 않은(기록할 자료가 들어있는)
  //가장 마지막 [페이지번호] 를 얻는다.
  //
  //실제는 맨뒤부터 검사하여 <0xff> 가 아닌 자료가 발견된 [페이지번호] 가 해당.
  //
  //이 함수는 EEprom 용량이 큰 AVR 의 경우, 전체를 다 기록하는 방식으로는 너무 시간이
  //많이 걸려서 유요한 부분 까지만 기록하기 위한 것.
  //}-------------------------------------------------------------------

  //[VAR]
  //{
      int  i;

  //}

  //[전역변수]{---------
  struct 전역변수  *gv;
  전역변수_위치얻기(&gv);
  //}-----------------

  //맨 뒤부터 <0xff> 가 아닌 자료 주소 찾기.
  for(i = (gv->AVR명세.eep크기 - 1); i >= 0; i--)
  {
    if(gv->eeprom[i] != 0xff)
    {
      //이 [주소] 가 포함된 [단위묶음] 이 찾고자 하는 [단위묶음].
      (*r채워진끝단위묶음번호) = (i/d_AVRINFO_eep처리단위);

      //처리할 것이 있다.
      return(true);

    }

  }

  //여기까지 온것은 <전역변수:eeprom[]> 의 모든 영역이 <0xff> 인 것으로
  //처리할 것이 전혀 없는 것.
  return(false);

}

bool Ide_설정비트정보_존재확인(struct 설정비트정보  *p정보8개)
{
  //[2011.11.08.화][생성!!!]{-------------------------------
  //전달받은 <struct 설정비트정보 [8]> 이 존재하는지 확인.
  //
  //모든 <이름> == "-" 인 경우는 아예 해당 설정정보가 존재하지 않는것.
  //ATmega16 의 경우는 [확장설정] 이 아예 존재하지 않는다.
  //이 경우 [자동진행] 시 건너뛰어야 할때 이 함수가 필요.
  //}------------------------------------------------------

  //[VAR]
  //{
      int  i;

  //}

  //[정보 존재 확인]
  //{
      for(i = 0; i < 8; i++)
      {
        //한개라도 [이름] 이 있는 경우는 [설정비트] 가 존재하는 것으로 본다.
        if(p정보8개[i].이름[0] != '-') return(true);

      }

      //여기까지 온 것은 모두 '-' 으로 설정정보 자체가 존재하지 않는것으로 본다.
      return(false);

  //}

}







