/*
 * XPT2046_TP_Access.c
 *
 *  Created on: 2024/11/22
 *      Author: egaono-electronics
 */

#include "XPT2046_TP_Access.h"

#include "Modules_Lib.h"

#include def_H_Periph_SPI


#include <string.h>



//------------------------------------------------------
// タッチパネル位置取得用パラメータの構造体の宣言
//------------------------------------------------------
struct sParam_Position_TP GLB_structParam_Position_TP;



//----------------------------------------------------------
// XPT2046初期化
//----------------------------------------------------------
// 引数:
//    なし


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


  //------------------------------------
  // LCD Touch Panel : T_IRQピン初期化
  //------------------------------------
  // T_IRQピンを入力に設定
  __HAL_RCC_GPIOC_CLK_ENABLE();

  GPIO_InitStructure.Pin = def_GPIO_PIN_x_LCD_T_IRQ;
  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
  GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(def_GPIOx_LCD_T_IRQ, &GPIO_InitStructure);



  //----------------------------------------------------------
  // SPIx : Handle SPI用パラメータの構造体を初期化
  //----------------------------------------------------------
  // 引数;
  // uint8_t *puint8_aSPI_TxBuffer : SPI送信Bufferのポインタ
  // uint8_t *puint8_aSPI_RxBuffer : SPI受信Bufferのポインタ

  // struct sParam_Handle_SPIx  *pstructParam_Handle_SPIx
  //              Handle SPI用パラメータの構造体のポインタ


  // 戻り値;
  //    なし
  //----------------------------------------------------------
  Initialize_Parameter_SPIx(GLB_uint8_aSPI2_TxBuffer,
                            GLB_uint8_aSPI2_RxBuffer,
                            &GLB_structParam_Handle_SPI2);


  //------------------------------------
  // Initialize SPI 2 : Master
  //------------------------------------
  //------------------------------------------------------------
  // SPIx 初期化
  //------------------------------------------------------------
  // 引数;
  // SPI_TypeDef *SPIx :
  //        where x can be 1 or 2 to select the SPI peripheral.
  // SPI_HandleTypeDef *pSpiHandle : SPI handler declaration

  // uint32_t uint32_SPI_Mode :
  //                        SPI_MODE_MASTER or SPI_MODE_SLAVE

  // uint32_t uint32_BaudRatePrescaler : SPIクロック 分周設定

  // uint16_t uint16_SPI_CLKPolarityL :
  //    clock polarity : SPI_POLARITY_LOW or SPI_POLARITY_HIGH


  // 戻り値;
  //    0 : OK
  //    1 : NG
  //------------------------------------------------------------
  Initialize_SPIx(def_SPIx_TP,
                  &def_Handle_SPIx_TP,
                  SPI_MODE_MASTER,
                  SPI_BAUDRATEPRESCALER_32,
                  SPI_POLARITY_LOW);
}



//----------------------------------------------------------
// Touch Panel 位置取得
//----------------------------------------------------------
// 引数;
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

// struct sParam_Position_TP *pstructParam_Position_TP :
//      タッチパネル位置取得用パラメータの構造体のポインタ


// 戻り値;
//   -1 : 処理中
//    0 : OK終了
//    1 : NG終了
//----------------------------------------------------------
int16_t Get_Position_TouchPanel(uint8_t *puint8_JobNum,
        struct sParam_Position_TP *pstructParam_Position_TP)
{
  static uint8_t STC_uint8_JobNum_TP;  // タッチパネル処理番号


  int16_t int16_I;
  int16_t int16_Point_XY;
  int16_t int16_Point;
  int32_t int32_Total;

  int16_t int16_Return;


  switch(*puint8_JobNum)
  {
  case 0:
    STC_uint8_JobNum_TP = 0;  // タッチパネル処理番号初期化


    pstructParam_Position_TP->uint16_Position_TP_Buffer = 0;
                                    // 位置情報保存位置初期化


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

  case 1:
    //----------------------------------------------------------
    // Touch PanelのXY位置取得
    //----------------------------------------------------------
    // 引数;
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // struct sParam_Position_TP *pstructParam_Position_TP :
    //      タッチパネル位置取得用パラメータの構造体のポインタ


    // 戻り値;
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //    2 : TP OFF
    //----------------------------------------------------------
    int16_Return = Get_XYZ_TP(&STC_uint8_JobNum_TP,
                              pstructParam_Position_TP);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }
    else if(int16_Return >= 1){
      // 1 : NG
      // 2 : TP OFF
      *puint8_JobNum = 0;  // 処理番号初期化
      int16_Return = 1;    // NG or TP OFF
      break;
    }


    //----------------------------------------------------------
    // 位置情報取得
    //----------------------------------------------------------
    // 位置情報データにフィルタ処理をした後、平均する。
    //----------------------------------------------------------

    //----------------------------------------------------------
    // 配列Bufferに取り込んだXY位置データの最後の場所を求める。
    //----------------------------------------------------------
    if(pstructParam_Position_TP->
                            uint16_Position_TP_Buffer == 0){
      int16_Point_XY
        = pstructParam_Position_TP->int16_Size_TP_Buffer - 1;
    }
    else{
      int16_Point_XY
            = (int16_t)pstructParam_Position_TP->
                                uint16_Position_TP_Buffer - 1;
    }


    //----------------------------------------------------------
    // X位置
    //----------------------------------------------------------
    // 位置データの最後の場所をセット
    int16_Point = int16_Point_XY;

    // 取り込んだデータをソート用の配列にセットする。
    for(int16_I = 0;
        int16_I < pstructParam_Position_TP->
                                int16_Number_Get_TP_XY;
        int16_I++){
      pstructParam_Position_TP->int16_aSort[int16_I]
          = (int16_t)pstructParam_Position_TP->
                            uint16_aTP_Buffer_X[int16_Point];
      int16_Point--;
      if(int16_Point < 0){
        int16_Point = pstructParam_Position_TP->
                                    int16_Size_TP_Buffer - 1;
      }
    }


    // 小さい順に並べる。
    Sort_Small_to_Large(
            pstructParam_Position_TP->int16_Number_Get_TP_XY,
            pstructParam_Position_TP->int16_aSort);
    if(pstructParam_Position_TP->
        int16_aSort[pstructParam_Position_TP->
                                int16_Number_TP_Except_F
        + pstructParam_Position_TP->int16_Number_TP_Average - 1]
        - pstructParam_Position_TP->
        int16_aSort[pstructParam_Position_TP->
                                int16_Number_TP_Except_F]
                                            > def_MAX_Diff_TP){
      *puint8_JobNum = 0;  // 処理番号初期化
      int16_Return = 1;    // NG終了
      break;
    }


    // 平均値算出のために位置データを平均個数分加算する。
    int32_Total = 0;

    // 取得データの前後のデータは捨てて、
    //                          中間部分だけをセットする。
    for(int16_I = pstructParam_Position_TP->
                                    int16_Start_TP_Average;
        int16_I <= pstructParam_Position_TP->
                                    int16_End_TP_Average;
        int16_I++){
      int32_Total += (int32_t)pstructParam_Position_TP->
                                        int16_aSort[int16_I];
    }

    // X位置の平均値をセット
    pstructParam_Position_TP->uint16_aPosition_TP_XYZ[0]
        = (uint16_t)(int32_Total
        / (int32_t)pstructParam_Position_TP->
                                    int16_Number_TP_Average);
    //----------------------------------------------------------


    //----------------------------------------------------------
    // Y位置
    //----------------------------------------------------------
    // 位置データの最後の場所をセット
    int16_Point = int16_Point_XY;

    // 取り込んだデータをソート用の配列にセットする。
    for(int16_I = 0;
        int16_I < pstructParam_Position_TP->
                                    int16_Number_Get_TP_XY;
        int16_I++){
      pstructParam_Position_TP->int16_aSort[int16_I]
          = (int16_t)pstructParam_Position_TP->
                            uint16_aTP_Buffer_Y[int16_Point];
      int16_Point--;
      if(int16_Point < 0){
        int16_Point
            = pstructParam_Position_TP->
                                    int16_Size_TP_Buffer - 1;
      }
    }


    // 小さい順に並べる。
    Sort_Small_to_Large(
            pstructParam_Position_TP->int16_Number_Get_TP_XY,
            pstructParam_Position_TP->int16_aSort);
    if(pstructParam_Position_TP->
        int16_aSort[pstructParam_Position_TP->
                                    int16_Number_TP_Except_F
        + pstructParam_Position_TP->
                                int16_Number_TP_Average - 1]
        - pstructParam_Position_TP->
        int16_aSort[pstructParam_Position_TP->
                                    int16_Number_TP_Except_F]
                                        > def_MAX_Diff_TP){
      *puint8_JobNum = 0;  // 処理番号初期化
      int16_Return = 1;    // NG終了
      break;
    }


    // 平均値算出のために位置データを平均個数分加算する。
    int32_Total = 0;

    // 取得データの前後のデータは捨てて、
    //                              中間部分だけをセットする。
    for(int16_I = pstructParam_Position_TP->
                                    int16_Start_TP_Average;
        int16_I <= pstructParam_Position_TP->
                                    int16_End_TP_Average;
        int16_I++){
      int32_Total += (int32_t)pstructParam_Position_TP->
                                        int16_aSort[int16_I];
    }

    // Y位置の平均値をセット
    pstructParam_Position_TP->uint16_aPosition_TP_XYZ[1]
        = (uint16_t)(int32_Total
        / (int32_t)pstructParam_Position_TP->
                                    int16_Number_TP_Average);
    //----------------------------------------------------------


    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = 0;    // OK終了
    break;

  default:
    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = 1;    // NG終了
    break;
  }

  return(int16_Return);
}



//----------------------------------------------------------
// Touch PanelのXYZ位置取得
//----------------------------------------------------------
// 引数;
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

// struct sParam_Position_TP *pstructParam_Position_TP :
//      タッチパネル位置取得用パラメータの構造体のポインタ


// 戻り値;
//   -1 : 処理中
//    0 : OK終了
//    1 : NG終了
//    2 : TP OFF
//----------------------------------------------------------
int16_t Get_XYZ_TP(uint8_t *puint8_JobNum,
        struct sParam_Position_TP *pstructParam_Position_TP)
{
  static uint8_t STC_uint8_JobNum_TP;  // タッチパネル処理番号

  static uint16_t STC_uint16_Count_TP;  // 位置情報取得回数
  static int16_t STC_int16_Count_ON;    // ON検出回数カウンタ
  static int16_t STC_int16_Count_OFF;   // OFF検出回数カウンタ
  static int16_t STC_int16_Data_Valid;  // 有効回数カウンタ

  int16_t int16_Return;

  GPIO_PinState gpio_PinState;


  switch(*puint8_JobNum)
  {
  case 0:
    STC_uint8_JobNum_TP = 0;  // タッチパネル処理番号初期化

    STC_uint16_Count_TP = 0;  // 位置情報取得回数初期化
    STC_int16_Count_ON = 0;   // ON検出回数カウンタクリア
    STC_int16_Count_OFF = 0;  // OFF検出回数カウンタクリア

    STC_int16_Data_Valid = 0;  // 有効回数カウンタクリア


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

  case 1:
    //----------------------------------------------------------
    // LCD T_IRQがLowになるのを検出 :
    //          タッチパネルが押されると Low になる。
    //----------------------------------------------------------
    gpio_PinState
        = HAL_GPIO_ReadPin(def_GPIOx_LCD_T_IRQ,
                           def_GPIO_PIN_x_LCD_T_IRQ);
    if(gpio_PinState == GPIO_PIN_RESET){
      // Lowを検出 : タッチパネルが押されている。
      STC_int16_Count_ON++;  // ON検出回数カウンタインクリメント

      // 規定回数検出したらタッチパネルが押されたとみなす。
      if(STC_int16_Count_ON >= (int16_t)def_Count_TP_ON){
        // ON検出回数カウンタが規定回数に達した。

        (*puint8_JobNum)++;  // 次の処理番号に移行する。
        int16_Return = -1;   // 処理継続
        break;
      }
    }
    else{
      // Highを検出 : タッチパネルが押されていない。
      STC_int16_Count_ON = 0;  // ON検出回数カウンタクリア
    }


    int16_Return = -1;  // 処理継続
    break;  // 処理番号維持 : 現在の処理番号をループ

  case 2:
    //--------------------------------------------------
    // タッチパネルのXY位置取得開始
    //--------------------------------------------------
    // 最初のデータを規定数捨てる。
    //--------------------------------------------------
    // LCD T_IRQがHighかを監視
    gpio_PinState
        = HAL_GPIO_ReadPin(def_GPIOx_LCD_T_IRQ,
                           def_GPIO_PIN_x_LCD_T_IRQ);
    if(gpio_PinState == GPIO_PIN_RESET){
      // Lowを検出 : タッチパネルが押されている。
      STC_int16_Count_OFF = 0;  // OFF検出回数カウンタクリア
    }
    else{
      // Highを検出 : タッチパネルが押されていない。
      STC_int16_Data_Valid = 0;  // 有効回数カウンタクリア

      STC_int16_Count_OFF++;
                        // OFF検出回数カウンタインクリメント

      // タッチされていない状態が規定回数続いたか判定する。
      if(STC_int16_Count_OFF >= (int16_t)def_Count_TP_OFF){
        // 規定回数続けてOFFになった。
        pstructParam_Position_TP->int16_vTimer_TP_Interval
                          = (int16_t)def_Time_Interval_TP;
                                    // 処理終了待ち時間セット

        *puint8_JobNum = 4;  // TP OFF処理に移行する。
        int16_Return = -1;   // 処理継続
        break;
      }
    }


    //----------------------------------------------------------
    // Touch PanelのXY位置データ取得
    //----------------------------------------------------------
    // 引数;
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // uint16_t *puint16_aTP_Buffer_X :
    //                          X位置を格納するBufferのポインタ
    // uint16_t *puint16_aTP_Buffer_Y :
    //                          Y位置を格納するBufferのポインタ
    // uint16_t uint16_Position_TP_Buffer : Buffer格納位置

    // 戻り値;
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Get_Data_XY_TP(&STC_uint8_JobNum_TP,
                                pstructParam_Position_TP->
                                        uint16_aTP_Buffer_X,
                                pstructParam_Position_TP->
                                        uint16_aTP_Buffer_Y,
                                pstructParam_Position_TP->
                                    uint16_Position_TP_Buffer);
    if(int16_Return != 0){
      // OK終了でない場合
      int16_Return = -1;  // 処理継続
      break;  // 処理番号維持 : 現在の処理番号をループ
    }


    STC_int16_Data_Valid++;  // 有効回数カウンタインクリメント

    // 最初のデータを捨てるための有効回数カウンタの判定
    if(STC_int16_Data_Valid
            >= pstructParam_Position_TP->int16_Number_TP_Idle){
      // 有効回数に達した場合

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


    int16_Return = -1;  // 処理継続
    break;  // 処理番号維持 : 現在の処理番号をループ

  case 3:
    //--------------------------------------------------
    // タッチパネルのXY位置取得
    //--------------------------------------------------
    // LCD T_IRQがHighかを監視
    gpio_PinState
        = HAL_GPIO_ReadPin(def_GPIOx_LCD_T_IRQ,
                           def_GPIO_PIN_x_LCD_T_IRQ);
    if(gpio_PinState == GPIO_PIN_RESET){
      // Lowを検出 : タッチパネルが押されている。
      STC_int16_Count_OFF = 0;  // OFF検出回数カウンタクリア
    }
    else{
      // Highを検出 : タッチパネルが押されていない。
      STC_int16_Count_OFF++;
                          // OFF検出回数カウンタインクリメント

      // タッチされていない状態が規定回数続いたか判定する。
      if(STC_int16_Count_OFF >= (int16_t)def_Count_TP_OFF){
        // 規定回数続けてOFFになった。
        pstructParam_Position_TP->int16_vTimer_TP_Interval
                          = (int16_t)def_Time_Interval_TP;
                                    // 処理終了待ち時間セット

        *puint8_JobNum = 4;  // TP OFF処理に移行する。
        int16_Return = -1;   // 処理継続
        break;
      }
    }


    //----------------------------------------------------------
    // Touch PanelのXY位置データ取得
    //----------------------------------------------------------
    // 引数;
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // uint16_t *puint16_aTP_Buffer_X :
    //                          X位置を格納するBufferのポインタ
    // uint16_t *puint16_aTP_Buffer_Y :
    //                          Y位置を格納するBufferのポインタ
    // uint16_t uint16_Position_TP_Buffer : Buffer格納位置

    // 戻り値;
    //   -1 : 処理中
    //    0 : OK終了
    //    1 : NG終了
    //----------------------------------------------------------
    int16_Return = Get_Data_XY_TP(&STC_uint8_JobNum_TP,
                                pstructParam_Position_TP->
                                        uint16_aTP_Buffer_X,
                                pstructParam_Position_TP->
                                        uint16_aTP_Buffer_Y,
                                pstructParam_Position_TP->
                                    uint16_Position_TP_Buffer);
    if(int16_Return != 0){
      // OK終了でない場合
      int16_Return = -1;  // 処理継続
      break;  // 処理番号維持 : 現在の処理番号をループ
    }


    pstructParam_Position_TP->uint16_Position_TP_Buffer++;
        // タッチパネル位置バッファの保存位置インクリメント
    if(pstructParam_Position_TP->uint16_Position_TP_Buffer
        >= (uint16_t)pstructParam_Position_TP->
                                    int16_Size_TP_Buffer){
      // 保存位置が末尾に達したら、保存位置を先頭に戻す。
      pstructParam_Position_TP->uint16_Position_TP_Buffer = 0;
    }


    //----------------------------------------------------------
    // STC_uint16_Count_TP が def_Number_Get_TP_XY 以上になったら、
    // 呼び出し側で位置の判定を行う。
    //----------------------------------------------------------

    STC_uint16_Count_TP++;  // 位置情報取得回数インクリメント

    // 規定回数に達したらOK終了する。
    if(STC_uint16_Count_TP
        >= (uint16_t)pstructParam_Position_TP->
                                    int16_Number_Get_TP_XY){
      // 規定回数に達した場合
      *puint8_JobNum = 0;  // 処理番号初期化
      int16_Return = 0;    // OK終了
      break;
    }


    int16_Return = -1;  // 処理継続
    break;  // 処理番号維持 : 現在の処理番号をループ

  case 4:
    //--------------------------------------
    // TP OFF処理
    //--------------------------------------
    // 時間経過判定
    if(pstructParam_Position_TP->int16_vTimer_TP_Interval > 0){
      // 時間が経過していない。
      int16_Return = -1;   // 処理継続
      break;  // 処理番号維持 : 現在の処理番号をループ
    }


    // タッチされていない状態になった。
    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = 2;    // TP OFF
    break;

  default:
    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = 1;    // NG終了
    break;
  }

  return(int16_Return);
}



//----------------------------------------------------------
// Touch PanelのXY位置データ取得
//----------------------------------------------------------
// 引数;
// uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

// uint16_t *puint16_aTP_Buffer_X :
//                          X位置を格納するBufferのポインタ
// uint16_t *puint16_aTP_Buffer_Y :
//                          Y位置を格納するBufferのポインタ
// uint16_t uint16_Position_TP_Buffer : Buffer格納位置


// 戻り値;
//   -1 : 処理中
//    0 : OK終了
//    1 : NG終了
//----------------------------------------------------------
int16_t Get_Data_XY_TP(uint8_t *puint8_JobNum,
                       uint16_t *puint16_aTP_Buffer_X,
                       uint16_t *puint16_aTP_Buffer_Y,
                       uint16_t uint16_Position_TP_Buffer)
{
  static uint8_t STC_uint8_JobNum_SPI;  // SPI処理番号

  static int16_t STC_int16_Value_Wait_SPI_TxRx;
                                    // SPI送受信待ちの値


  int16_t int16_Return;

  uint16_t uint16_Position;


  switch(*puint8_JobNum)
  {
  case 0:
    STC_uint8_JobNum_SPI = 0;  // SPI処理番号初期化


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

  case 1:
    // X位置取得コマンド
    def_uint8_SPIx_TxBuffer[0] = (uint8_t)def_Command_TP_X;

    // SPI送信データ数セット
    def_int16_vSPIx_TxNumber = 1;


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

  case 2:  // タッチパネルのXY位置取得開始
    //----------------------------------
    // SPI送信 : NSS ONのまま
    //----------------------------------
    //----------------------------------------------------------
    // SPIx  Master送受信
    //----------------------------------------------------------
    // 引数;
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // SPI_HandleTypeDef *pHandle_SPIx : SPI handler declaration

    // IRQn_Type DMA_Stream_IRQn_Transmit_SPIx : SPI DMA Transmit IRQn
    // IRQn_Type DMA_Stream_IRQn_Receive_SPIx : SPI DMA Receive IRQn

    // struct sParam_Handle_SPIx *pstructParam_Handle_SPIx :
    //              Handle SPI用パラメータの構造体のポインタ

    // GPIO_TypeDef *pGPIOx_SPIx_NSS : SPIx_NSS のGPIOポート
    // uint16_t uint16_GPIO_Pin_x_SPIx_NSS : SPIx_NSS のGPIOピン

    // int16_t int16_Value_Wait_SPI_TxRx : SPI送受信待ちの値

    // int16_t int16_NSS_OnOff : 送信終了時NSS ON/OFF選択
    //    0 : 送信後 NSSをOFFにする。
    //    1 : 送信後 NSSをONのままにする。

    // 戻り値;
    //   -1 : 処理中
    //    0 : OK
    //    1 : NG
    //----------------------------------------------------------
    int16_Return
        = SPIx_Master_TxRxByte(&STC_uint8_JobNum_SPI,
                               &Handle_SPI2,
                               DMA1_Stream4_IRQn,
                               DMA1_Stream3_IRQn,
                               &def_structParam_Handle_SPIx,
                               def_GPIOx_SPI2_NSS,
                               def_GPIO_PIN_x_SPI2_NSS,
                               STC_int16_Value_Wait_SPI_TxRx,
                               1);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      *puint8_JobNum = 0;  // 処理番号初期化
      break;  // NG終了
    }


    // Dummyコマンド : 2byte読み込み
    def_uint8_SPIx_TxBuffer[0] = 0;
    def_uint8_SPIx_TxBuffer[1] = 0;

    // SPI送信データ数セット
    def_int16_vSPIx_TxNumber = 2;


    GLB_structParam_Position_TP.int16_vTimer_TP_Interval
                                        = def_Time_Convert_TP;
                                        // 変換時間待ちセット


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

  case 3:
    // 変換時間待ち
    if(GLB_structParam_Position_TP.int16_vTimer_TP_Interval > 0){
      // 時間が経過していない。
      int16_Return = -1;   // 処理継続
      break;  // 処理番号維持 : 現在の処理番号をループ
    }


    // SPI送信 : NSS OFF : X位置読み込み
    //----------------------------------------------------------
    // SPIx  Master送受信
    //----------------------------------------------------------
    // 引数;
    // uint8_t *puint8_JobNum : 処理番号を格納する変数のポインタ

    // SPI_HandleTypeDef *pHandle_SPIx : SPI handler declaration

    // IRQn_Type DMA_Stream_IRQn_Transmit_SPIx : SPI DMA Transmit IRQn
    // IRQn_Type DMA_Stream_IRQn_Receive_SPIx : SPI DMA Receive IRQn

    // struct sParam_Handle_SPIx *pstructParam_Handle_SPIx :
    //              Handle SPI用パラメータの構造体のポインタ

    // GPIO_TypeDef *pGPIOx_SPIx_NSS : SPIx_NSS のGPIOポート
    // uint16_t uint16_GPIO_Pin_x_SPIx_NSS : SPIx_NSS のGPIOピン

    // int16_t int16_Value_Wait_SPI_TxRx : SPI送受信待ちの値

    // int16_t int16_NSS_OnOff : 送信終了時NSS ON/OFF選択
    //    0 : 送信後 NSSをOFFにする。
    //    1 : 送信後 NSSをONのままにする。

    // 戻り値;
    //   -1 : 処理中
    //    0 : OK
    //    1 : NG
    //----------------------------------------------------------
    int16_Return
        = SPIx_Master_TxRxByte(&STC_uint8_JobNum_SPI,
                               &Handle_SPI2,
                               DMA1_Stream4_IRQn,
                               DMA1_Stream3_IRQn,
                               &def_structParam_Handle_SPIx,
                               def_GPIOx_SPI2_NSS,
                               def_GPIO_PIN_x_SPI2_NSS,
                               STC_int16_Value_Wait_SPI_TxRx,
                               0);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      // NG
      *puint8_JobNum = 0;  // 処理番号初期化
      break;  // NG終了
    }


    //----------------------------------------------------------
    // X位置取得
    //----------------------------------------------------------
    uint16_Position
        = (uint16_t)(def_uint8_SPIx_RxBuffer[0] & 0x7F);

    uint16_Position <<= 5;

    def_uint8_SPIx_RxBuffer[1] >>= 3;
    uint16_Position
        |= (uint16_t)(def_uint8_SPIx_RxBuffer[1] & 0x1F);


    // X位置セット
    puint16_aTP_Buffer_X[uint16_Position_TP_Buffer]
                                        = uint16_Position;
    //----------------------------------------------------------


    // Y位置取得コマンド
    def_uint8_SPIx_TxBuffer[0] = (uint8_t)def_Command_TP_Y;

    // SPI送信データ数セット
    def_int16_vSPIx_TxNumber = 1;


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

  case 4:
    // SPI送信 : NSS ONのまま
    int16_Return
        = SPIx_Master_TxRxByte(&STC_uint8_JobNum_SPI,
                               &Handle_SPI2,
                               DMA1_Stream4_IRQn,
                               DMA1_Stream3_IRQn,
                               &def_structParam_Handle_SPIx,
                               def_GPIOx_SPI2_NSS,
                               def_GPIO_PIN_x_SPI2_NSS,
                               STC_int16_Value_Wait_SPI_TxRx,
                               1);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      *puint8_JobNum = 0;  // 処理番号初期化
      break;  // NG終了
    }


    // Dummyコマンド : 2byte読み込み
    def_uint8_SPIx_TxBuffer[0] = 0;
    def_uint8_SPIx_TxBuffer[1] = 0;

    // SPI送信データ数セット
    def_int16_vSPIx_TxNumber = 2;


    GLB_structParam_Position_TP.int16_vTimer_TP_Interval
                                        = def_Time_Convert_TP;
                                        // 変換時間待ちセット


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

  case 5:
    // 変換時間待ち
    if(GLB_structParam_Position_TP.int16_vTimer_TP_Interval > 0){
      // 時間が経過していない。
      int16_Return = -1;   // 処理継続
      break;  // 処理番号維持 : 現在の処理番号をループ
    }


    // SPI送信 : NSS OFF : Y位置読み込み
    int16_Return
        = SPIx_Master_TxRxByte(&STC_uint8_JobNum_SPI,
                               &Handle_SPI2,
                               DMA1_Stream4_IRQn,
                               DMA1_Stream3_IRQn,
                               &def_structParam_Handle_SPIx,
                               def_GPIOx_SPI2_NSS,
                               def_GPIO_PIN_x_SPI2_NSS,
                               STC_int16_Value_Wait_SPI_TxRx,
                               0);
    if(int16_Return == -1){
      // 処理中
      break;  // 処理番号維持 : 処理継続 : 現在の処理番号をループ
    }

    if(int16_Return != 0){
      *puint8_JobNum = 0;  // 処理番号初期化
      break;  // NG終了
    }


    //----------------------------------------------------------
    // Y位置取得
    //----------------------------------------------------------
    uint16_Position
        = (uint16_t)(def_uint8_SPIx_RxBuffer[0] & 0x7F);
    uint16_Position <<= 5;

    def_uint8_SPIx_RxBuffer[1] >>= 3;
    uint16_Position
        |= (uint16_t)(def_uint8_SPIx_RxBuffer[1] & 0x1F);


    // Y位置セット
    puint16_aTP_Buffer_Y[uint16_Position_TP_Buffer]
                                        = uint16_Position;
    //----------------------------------------------------------


    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = 0;    // OK終了
    break;

  default:
    *puint8_JobNum = 0;  // 処理番号初期化
    int16_Return = 1;    // NG終了
    break;
  }

  return(int16_Return);
}
