#include "ys32md211_nucleo.h"

/**
 * @brief  LED initialization
 * @param  None
 * @retval None
 */
void BSP_LED_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    LED1_GPIO_CLK_ENABLE();

    GPIO_InitStructure.GPIO_Pin = LED1_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_VeryHigh;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);
}

/**
 * @brief  Key initialization
  * @param  KeyMode Specifies Key mode.
  *   This parameter can be one of following parameters:   
  *     @arg KEY_MODE_GPIO: Key will be used as simple IO(GPIO_PuPd_UP)
  *     @arg KEY_MODE_EXTI_RISING:         Key will be connected to EXTI line with RISING interrupt(GPIO_PuPd_DOWN)
  *     @arg KEY_MODE_EXTI_FALLING:        Key will be connected to EXTI line with FALLING interrupt(GPIO_PuPd_UP)
  *     @arg KEY_MODE_EXTI_RISING_FALLING: Key will be connected to EXTI line with RISING_FALLING interrupt(GPIO_PuPd_NOPULL)
 * @retval None
 */
void BSP_KEY_Init(KEY_TypeDef KeyMode)
{
    GPIO_InitTypeDef GPIO_InitStructure;

#ifdef BSP_KEY_EXTI_ENABLE
    NVIC_InitTypeDef NVIC_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
#endif

    KEY1_GPIO_CLK_ENABLE();

    GPIO_InitStructure.GPIO_Pin = KEY1_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_VeryHigh;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    if (KeyMode == KEY_MODE_GPIO)
    {
        /* Configure KEY pin as input */
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
    }
    else
    {
#ifdef BSP_KEY_EXTI_ENABLE

        EXTI_EXTILineConfig(KEY1_EXTI_Port, KEY1_EXTI_PinSource);
        EXTI_InitStructure.EXTI_Line = KEY1_EXTI_Line;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;

        if (KeyMode == KEY_MODE_EXTI_RISING)
        {
            /* Configure KEY pin as input with External interrupt */
            EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
            GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
        }
        else if (KeyMode == KEY_MODE_EXTI_FALLING)
        {
            /* Configure KEY pin as input with External interrupt */
            EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
            GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        }
        else
        {
            EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
            GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        }
        GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
        EXTI_Init(&EXTI_InitStructure);

        NVIC_InitStructure.NVIC_IRQChannel = KEY1_EXTI_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
#endif
    }
}

//void KEY1_EXTI_IRQHandler(void)
//{
//  if(EXTI_GetITStatus(KEY1_EXTI_Line) != RESET)
//  {
//    EXTI_ClearITPendingBit(KEY1_EXTI_Line);
//  }
//}

/**
 * @brief  Serial port initialization (printing debugging information)
 * @param  None
 * @retval None
 */
void BSP_UART_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    UART_InitTypeDef UART_InitStructure;

    UARTx_TX_GPIO_CLK_ENABLE();
    UARTx_CLK_ENABLE();

    //=========================================================================
    GPIO_PinAFConfig(UARTx_TX_GPIO_PORT, UARTx_TX_PinSource, UARTx_TX_GPIO_AF);

    GPIO_InitStructure.GPIO_Pin = UARTx_TX_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_VeryHigh;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(UARTx_TX_GPIO_PORT, &GPIO_InitStructure);

    //=========================================================================
    UART_InitStructure.UART_BaudRate = USER_UART_BAUD_RATE;
    UART_InitStructure.UART_WordLength = UART_WordLength_8b;
    UART_InitStructure.UART_StopBits = UART_StopBits_1;
    UART_InitStructure.UART_Parity = UART_Parity_No;
    UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;
    UART_InitStructure.UART_Mode = UART_Mode_Tx;
    UART_Init(USER_UARTx, &UART_InitStructure);

    UART_Cmd(USER_UARTx, ENABLE);
}

/**
 * @brief  The serial port sends one byte
 * @param  Data: Print Data.
 * @retval None
 */
void BSP_UART_SendByte(uint8_t Data)
{
    while ((USER_UARTx->ISR & UART_FLAG_TXE) == RESET)
        ;
    USER_UARTx->TDR = Data;
}

/**
 * @brief  Remap printing.
 * @param  ch: Print Char.
 * @retval None
 */
#ifdef BSP_UART_REMAP_PRINT_ENABLE

int fputc(int ch, FILE *f)
{
    BSP_UART_SendByte(ch);
    return ch;
}
#endif
