/*
 * Detects_Pressed_USW.c
 *
 *  Created on: 2024/12/19
 *      Author: egaono-electronics
 */

#include "Detects_Pressed_USW.h"

#include "Time_Interval.h"



int16_t GLB_int16_USW_Init_Done = 0;  // USERスイッチ 初期化済みフラグ




//--------------------------------------------------
// USERスイッチ入力ピン初期化
//--------------------------------------------------
// 引数:
//    なし


// 戻り値:
//    なし
//--------------------------------------------------
void Initialize_USW(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;


  // Enable the GPIOs Clock
  def_GPIOx_CLK_ENABLE_USW();


  //----------------------------------------------------
  // USERスイッチ入力ピンの初期化
  //----------------------------------------------------
  // Configure USER Switch pin as input
  GPIO_InitStructure.Pin = def_GPIO_PIN_x_USW;
  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;

#ifdef def_USW_NOPULL
  GPIO_InitStructure.Pull = GPIO_NOPULL;
#else  // def_USW_NOPULL
  GPIO_InitStructure.Pull = GPIO_PULLUP;
#endif  // def_USW_NOPULL

  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(def_GPIOx_USW, &GPIO_InitStructure);
}



//----------------------------------------------------------
// USERスイッチ押下検出
//----------------------------------------------------------
// 引数;
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ


// 戻り値;
//   -1 : 検出なし
//    0 : 検出あり
//----------------------------------------------------------
int16_t Detects_Pressed_USW(uint8_t *puint8_JobNum)
{
  //----------------------------------------------------
  // 呼び出す関数の引数に使用する処理番号は、
  // 必ず static の変数宣言をしてください。
  //----------------------------------------------------
  static uint8_t STC_uint8_JobNum_Time;  // Time_Interval処理番号

  //------------------------------------------------------
  // Time_Interval用パラメータの構造体の宣言は、
  // 使用する関数内で、必ず static で宣言してください。
  //------------------------------------------------------
  // Time_Interval用パラメータの構造体の宣言
  //------------------------------------------------------
  static struct sParam_Time_Interval STC_structParam_Time_Interval;


  GPIO_PinState gpio_PinState;

  int16_t int16_Return;


  switch(*puint8_JobNum)
  {
  case 0:
    //--------------------------------------------------
    // 1回だけ case 0: を実行します。

    // その後は、case 1: を実行後、
    // case 2: ～ case 7: をループします。
    //--------------------------------------------------


    GLB_int16_USW_Init_Done = 0;  // USERスイッチ 初期化済みフラグ 初期化


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 1:
    // USERスイッチ 初期化済みフラグ判定
    if(GLB_int16_USW_Init_Done == 0){
      // USERスイッチ 初期化済みフラグが OFF の場合

      //----------------------------------------------
      // USERスイッチ入力ピン初期化
      //----------------------------------------------
      def_M_Initialize_USW();

      GLB_int16_USW_Init_Done = 1;  // USERスイッチ 初期化済みフラグ ON
    }


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 2:
    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_OFF){
      // USERスイッチは押されていない。
      int16_Return = -1;  // 処理継続
      break;  // 処理番号維持 : 現在の処理番号をループ
    }


    STC_uint8_JobNum_Time = 0;  // Time_Interval処理番号初期化
    STC_structParam_Time_Interval.uint32_Interval
        = (uint32_t)def_Time_Cancel_Chatt;  // 待ち時間をセット


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 3:  // チャタリング検出 1回目
    //----------------------------------------------------------
    // 時間待ち : 単位 mSec
    //----------------------------------------------------------
    // 戻り値が -1 以外になるまで、繰り返し呼び出してください。
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Time_Interval *pstructParam_Time_Interval :
    //              Time_Interval用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中 : 時間が経過していない。
    //    0 : OK終了 : 時間が経過した。
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Time_Interval(&STC_uint8_JobNum_Time,
                                 &STC_structParam_Time_Interval);
    if(int16_Return == -1){
      // 処理中 : 時間が経過していない。
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_OFF){
      // USERスイッチは押されていない。
      *puint8_JobNum = 2;
                // USERスイッチの状態入力に戻る。 : case 2:
      int16_Return = -1;   // 処理継続
      break;
    }


    STC_uint8_JobNum_Time = 0;  // Time_Interval処理番号初期化
    STC_structParam_Time_Interval.uint32_Interval
        = (uint32_t)def_Time_Cancel_Chatt;  // 待ち時間をセット


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 4:  // チャタリング検出 2回目
    //----------------------------------------------------------
    // 時間待ち : 単位 mSec
    //----------------------------------------------------------
    // 戻り値が -1 以外になるまで、繰り返し呼び出してください。
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Time_Interval *pstructParam_Time_Interval :
    //              Time_Interval用パラメータの構造体のポインタ

    // 戻り値:
    //   -1 : 処理中 : 時間が経過していない。
    //    0 : OK終了 : 時間が経過した。
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Time_Interval(&STC_uint8_JobNum_Time,
                                 &STC_structParam_Time_Interval);
    if(int16_Return == -1){
      // 処理中 : 時間が経過していない。
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_OFF){
      // USERスイッチは押されていない。
      *puint8_JobNum = 2;
                // USERスイッチの状態入力に戻る。 : case 2:
      int16_Return = -1;   // 処理継続
      break;
    }


    STC_uint8_JobNum_Time = 0;  // Time_Interval処理番号初期化
    STC_structParam_Time_Interval.uint32_Interval
        = (uint32_t)def_Time_Cancel_Chatt;  // 待ち時間をセット


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 5:  // チャタリング検出 3回目
    //----------------------------------------------------------
    // 時間待ち : 単位 mSec
    //----------------------------------------------------------
    // 戻り値が -1 以外になるまで、繰り返し呼び出してください。
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Time_Interval *pstructParam_Time_Interval :
    //              Time_Interval用パラメータの構造体のポインタ


    // 戻り値:
    //   -1 : 処理中 : 時間が経過していない。
    //    0 : OK終了 : 時間が経過した。
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Time_Interval(&STC_uint8_JobNum_Time,
                                 &STC_structParam_Time_Interval);
    if(int16_Return == -1){
      // 処理中 : 時間が経過していない。
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_OFF){
      // USERスイッチは押されていない。
      *puint8_JobNum = 2;
                // USERスイッチの状態入力に戻る。: case 2:
      int16_Return = -1;   // 処理継続
      break;
    }


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 6:
    //----------------------------------------------------------
    // USERスイッチがOFFになるのを待つ。
    //----------------------------------------------------------
    // USERスイッチの状態を入力
    gpio_PinState = HAL_GPIO_ReadPin(def_GPIOx_USW,
                                     def_GPIO_PIN_x_USW);
    if(gpio_PinState == def_USW_ON){
      // USERスイッチは押されている。
      int16_Return = -1;
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    STC_uint8_JobNum_Time = 0;  // Time_Interval処理番号初期化
    STC_structParam_Time_Interval.uint32_Interval
        = (uint32_t)def_Time_Release_SW;  // 待ち時間をセット


    (*puint8_JobNum)++;  // 次の処理番号に移行する。
    int16_Return = -1;   // 処理継続
    break;

  case 7:
    //----------------------------------------------------------
    // USERスイッチがOFFになった後、少し待つ。
    //----------------------------------------------------------

    //----------------------------------------------------------
    // 時間待ち : 単位 mSec
    //----------------------------------------------------------
    // 戻り値が -1 以外になるまで、繰り返し呼び出してください。
    //----------------------------------------------------------
    // 引数:
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Time_Interval *pstructParam_Time_Interval :
    //              Time_Interval用パラメータの構造体のポインタ

    // 戻り値:
    //   -1 : 処理中 : 時間が経過していない。
    //    0 : OK終了 : 時間が経過した。
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Time_Interval(&STC_uint8_JobNum_Time,
                                 &STC_structParam_Time_Interval);
    if(int16_Return == -1){
      // 処理中 : 時間が経過していない。
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }


    *puint8_JobNum = 2;  // 処理番号 2 に移行する。: case 2:
                         // case 2: ～ case 7: をループ
    int16_Return = 0;    // USERスイッチ押下検出ありをセット
    break;

  default:
    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = -1;   // 処理継続
    break;
  }

  return(int16_Return);
}
