 /**
  ******************************************************************************
  * @file    hyperterminal.h
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    12-January-2018
  * @brief   This file provides all the Hyperterminal driver functions.
  ********************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2018 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "hyperterminal.h"
#include "stm8l15x.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief Convert an Integer to a string.
  * @par Parameters:
  *   - str: The stringto be converted
  *   - intnum: The intger to be converted
  * @retval
  * None
  */
void Int2Str(char *str, u32 intnum)
{
  u32 i, Div = 1000000000, j = 0, Status = 0;
  for (i = 0; i < 10; i++)
  {
    str[j++] = (intnum / Div) + 48;
    intnum = intnum % Div;
    Div /= 10;
    if ((str[j-1] == '0') & (Status == 0))
    {
      j = 0;
    }
    else
    {
      Status++;
    }
  }
}

/**
  * @brief Convert a string to an integer.
  * @par Parameters:
  *   - str: The string to be converted
  *   - intnum: The intger to be converted
  * @retval
  *   - 1: Correct
  *   - 0: Error
  */
u8 Str2Int(char *inputstr, u32 *intnum)
{
  u8 i = 0, res = 0;
  u32 val = 0;
  if (inputstr[0] == '0' && (inputstr[1] == 'x' || inputstr[1] == 'X'))
  {
    if (inputstr[2] == '\0')
    {
      return 0;
    }
    for (i = 2; i < 11; i++)
    {
      if (inputstr[i] == '\0')
      {
        *intnum = val;
        res = 1; /* return 1; */
        break;
      }
      if (ISVALIDHEX(inputstr[i]))
      {
        val = (val << 4) + CONVERTHEX(inputstr[i]);
      }
      else
      {
        /* return 0; Invalid input */
        res = 0;
        break;
      }
    }
    if (i >= 11) res = 0; /* over 8 digit hex --invalid */
  }
  else /* max 10-digit decimal input */
  {
    for (i = 0;i < 11;i++)
    {
      if (inputstr[i] == '\0')
      {
        *intnum = val;
        /* return 1; */
        res = 1;
        break;
      }
      else if ((inputstr[i] == 'k' || inputstr[i] == 'K') && (i > 0))
      {
        val = val << 10;
        *intnum = val;
        res = 1;
        break;
      }
      else if ((inputstr[i] == 'm' || inputstr[i] == 'M') && (i > 0))
      {
        val = val << 20;
        *intnum = val;
        res = 1;
        break;
      }
      else if (ISVALIDDEC(inputstr[i]))
        val = val * 10 + CONVERTDEC(inputstr[i]);
      else
      {
        /* return 0; Invalid input */
        res = 0;
        break;
      }
    }
    if (i >= 11) res = 0; /* Over 10 digit decimal --invalid */
  }
  return res;
}

/**
  * @brief Get an integer from the HyperTerminal.
  * @par Parameters:
  *   - num: The inetger
  * @retval
  *   - 1: Correct
  *   - 0: Error
  */
u8 GetIntegerInput(u32 *num)
{
  char inputstr[16];
  while (1)
  {
    GetInputString(inputstr);
    if (inputstr[0] == '\0') continue;
    if ((inputstr[0] == 'a' || inputstr[0] == 'A') && inputstr[1] == '\0')
    {
      SerialPutString("User Cancelled \r\n");
      return 0;
    }
    if (Str2Int(inputstr, num) == 0)
    {
      SerialPutString("Error, Input again: \r\n");
    }
    else
    {
      return 1;
    }
  }
}

/**
  * @brief Test to see if a key has been pressed on the HyperTerminal.
  * @par Parameters:
  *   - key: The key pressed
  * @retval
  *   - 1: Correct
  *   - 0: Error
  */
u8 SerialKeyPressed(char *key)
{
  FlagStatus flag  ;
  /* First clear Rx buffer */
  flag = USART_GetFlagStatus(USART3, USART_FLAG_RXNE);
  if ( flag == SET)
  {
    *key = (char)USART3->DR;
    return 1;
  }
  else
  {
    return 0;
  }
}

/**
  * @brief Get a key from the HyperTerminal.
  * @par Parameters:
  *   None
  * @retval
  *   The Key Pressed
  */
char GetKey(void)
{
  char key = 0;
  /* Waiting for user input */
  while (1)
  {
    if (SerialKeyPressed((char*)&key)) break;
  }
  return key;
}

/**
  * @brief Print a character on the HyperTerminal.
  * @par Parameters:
  *   - c: The character to be printed
  * @retval
  *   None
  */
void SerialPutChar(char c)
{
  USART_SendData8(USART3, c);
  while ((USART3->SR & USART_SR_TXE ) != USART_SR_TXE );
}

/**
  * @brief Print a string on the HyperTerminal.
  * @par Parameters:
  *   - s: The string to be printed
  * @retval
  *   None
  */
void SerialPutString(char *s)
{
  while (*s != '\0')
  {
    SerialPutChar(*s);
    s ++;
  }
}

/**
  * @brief Get Input string from the HyperTerminal.
  * @par Parameters:
  *   - buffP: The input string
  * @retval
  *   None
  */
void GetInputString (char *buffP)
{
  int bytes_read = 0;
  char c = 0;
  do
  {
    c = GetKey();
    if (c == '\r')
      break;
    if (c == '\b') /* Backspace */
    {
      if (bytes_read > 0)
      {
        SerialPutString("\b \b");
        bytes_read --;
      }
      continue;
    }
    if (bytes_read >= CMD_STRING_SIZE )
    {
      SerialPutString("Command string size overflow\r\n");
      bytes_read = 0;
      continue;
    }
    if (c >= 0x20 && c <= 0x7E)
    {
      buffP[bytes_read++] = c;
      SerialPutChar(c);
    }
  }
  while (1);
  SerialPutString("\n\r");
  buffP[bytes_read] = '\0';
}

/**
  * @brief Display/Manage a Menu on HyperTerminal Window.
  * @par Parameters:
  *   None
  * @retval
  *   None
  */
void Main_Menu(void)
{
  char choice [70];
  bool bTreat;
  bool freq_error = FALSE;
  BEEP_Frequency_TypeDef freq;
  u32 freq_choice;
  while (1)
  {
    /* Display Menu on HyperTerminal Window */
    bTreat = FALSE ;
    SerialPutString("\r\n====================== STM8L-NUCLEO ===================\r\n");
    SerialPutString("This Application is basic example of UART interface with\r\n");
    SerialPutString("Windows Hyper Terminal. \r\n");
    SerialPutString("\r\n==========================================================\r\n");
    SerialPutString("                          APPLICATION MENU :\r\n");
    SerialPutString("\r\n==========================================================\r\n\n");
    SerialPutString(" 1 - Set LD2 off \r\n");
    SerialPutString(" 2 - Set LD2 on \r\n");
    SerialPutString(" 3 - Set LD2 blink \r\n");
    SerialPutString(" 4 - BEEPER ON \r\n");
    SerialPutString(" 5 - BEEPER OFF \r\n\n");
    SerialPutString("Enter your choice : ");
    GetInputString(choice);
    /* Set LD2 on */
    if (strcmp(choice,"1")== 0)
    {
      bTreat = TRUE;
      /* Disable TIM3 */
      TIM3_Cmd(DISABLE);
      GPIO_ResetBits(GPIOB, GPIO_Pin_5);
    }
    /* Set LD2 off */
    if ((strcmp(choice,"2") == 0))
    {
      bTreat = TRUE;
      /* Disable TIM3 */
      TIM3_Cmd(DISABLE);
      GPIO_SetBits(GPIOB, GPIO_Pin_5);
    }
    /* Set LD2 blink */
    if (strcmp(choice,"3") == 0)
    {
      bTreat = TRUE;
      /* Enable TIM3 */
      TIM3_Cmd(ENABLE);
    }
    /* BEEPER ON */
    if (strcmp(choice,"4") == 0)
    {
      bTreat = TRUE;
      freq_error = FALSE ;
      SerialPutString("\r\nPlease select a BEEP frequency :\r\n");
      SerialPutString("1 -  1KHz\r\n");
      SerialPutString("2 -  2KHz\r\n");
      SerialPutString("3 -  4KHz\r\n");
      SerialPutString("Choice : ");
      GetIntegerInput(&freq_choice);
      switch(freq_choice)
      {
      case 1 : freq = BEEP_Frequency_1KHz; break;
      case 2 : freq = BEEP_Frequency_2KHz; break;
      case 3 : freq = BEEP_Frequency_4KHz; break;
      default : SerialPutString("\n Selection ERROR "); freq_error = TRUE; break;
      }
      if (!freq_error)
      {
        BEEP_Cmd(DISABLE);
        BEEP_Init(freq);
        BEEP_Cmd(ENABLE);
      }
    }
    /* BEEPER OFF */
    if (strcmp(choice,"5") == 0)
    {
      bTreat = TRUE;
      BEEP_Cmd(DISABLE);
    }
    /* OTHERS CHOICE*/
    if (bTreat == FALSE)
    {
      SerialPutString(" wrong choice  \r\n");
    }
  } /* While(1)*/
}/* Main_Menu */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
