/**
  ******************************************************************************
  * @file    gpio.h
  * @author  Разваляев Алексей
  * @brief   Драйвер GPIO на основе PLIB035.
  *          Данный файл содержит определения типов, структур и прототипы функций
  *          для работы с UART, включая:
  *           + Структуры и typedef для работы с кнопками и светодиодами
  *           + Макросы для конфигурации режима пинов
  *           + Прототипы функций для инициализации и API драйвера
  *
  ******************************************************************************
  */
#ifndef __GPIO_H
#define __GPIO_H
//-- Includes ------------------------------------------------------------------
#include "plib035.h"
#include "retarget_conf.h"

//-- Defines -------------------------------------------------------------------
// Дефайны для режима пина      OutEnable,  AltFuncEnable,  DigitalEnable 
#define GPIO_PinMode_Unused     DISABLE,    DISABLE,        DISABLE
#define GPIO_PinMode_Input      DISABLE,    DISABLE,        ENABLE
#define GPIO_PinMode_Output     ENABLE,     DISABLE,        ENABLE
#define GPIO_PinMode_AltFunc    DISABLE,    ENABLE,         ENABLE

#ifndef LED_PWM_TICKS
#define LED_PWM_TICKS 15 ///< Количество тиков в периоде ШИМ
#endif
//-- Types ---------------------------------------------------------------------

/**
  * @brief Режимы работы светодиода
  */
typedef enum
{
  LED_IS_OFF = 0,       ///< Светодиод выключен
  LED_IS_ON = 1,        ///< Светодиод включен
  LED_IS_BLINKING = 2,  ///< Моргание светодиодом
  LED_IS_FADING = 3,    ///< Плавное моргание светодиодом
}GPIO_LEDStateTypeDef;

/**
  * @brief Структура светодиода
  */
typedef struct
{
  GPIO_LEDStateTypeDef state;     ///< Текущий режим работы светодиода
  
  GPIO_TypeDef  *LED_Port;        ///< GPIO порт ножки светодиода
  uint32_t      LED_Pin;          ///< GPIO пин ножки светодиода
  
  BitState      LED_ActiveLvl;    ///< Активный уровень ножки (при котором светодиод горит)
  uint32_t      LED_Period;       ///< Период моргания светодиода

  uint32_t      tickprev;
}GPIO_LEDTypeDef;

/**
  * @brief Структура кнопки
  */
typedef struct
{
  GPIO_TypeDef  *Sw_Port;         ///< GPIO порт ножки кнопки
  uint32_t      Sw_Pin;           ///< GPIO пин ножки кнопки
  
  BitState      Sw_ActiveLvl;     ///< Активный уровень ножки (при котором кнопка нажата)
  uint32_t      Sw_CurrentState;  ///< Текущее состояние кнопки
  uint32_t      Sw_FilterDelay;   ///< Фильтр от дребезга (в мс)

  uint32_t      tickprev; 
}GPIO_SwitchTypeDef;


//-- Exported functions prototypes ---------------------------------------------

/* Init functions */

void gpio_init(void);
GPIO_Init_TypeDef *gpio_get_init(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);


/* API functions*/

/** 
  * @addtogroup GPIO_SWITCH  Switch tools
  * @brief      Функции для работы с GPIO, как с кнопкой
  * @par Пример использования:
    @code
    MX_GPIO_Init(); // инициализация пина аппаратная
    
    // Инициализация кнопки на порте GPIOB, пин 0, активный уровень 1
    GPIO_SwitchTypeDef sw1;
    GPIO_Switch_Init(&sw1, GPIOB, GPIO_PIN_0, 1); // или дефайн SW_ON/SW_OFF

    // Считываем состояние кнопки
    if(GPIO_Read_Switch(&sw1))
    {
        // Кнопка нажата
        LED_ON();
    }
    else
    {
        // Кнопка отжата
        LED_OFF();
    }
    @endcode
  * @{
  */

/* Инициализировать кнопку (структуру кнопки) */
OperationStatus GPIO_Switch_Init(GPIO_SwitchTypeDef *sw, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, BitState SW_On_State);
/* Считать состоянии кнопки запуска */
int GPIO_Read_Switch(GPIO_SwitchTypeDef *swstart);

/** GPIO_SWITCH
  * @}
  */


/** 
  * @addtogroup GPIO_LEDS  LED tools
  * @brief      Функции для работы с GPIO, для управления светодиодом
  * @par Пример использования:
    @code
    // Инициализация светодиода на порте GPIOA, пин 5, активный уровень 0
    GPIO_LEDTypeDef led;
    GPIO_LED_Init(&led, GPIOA, GPIO_PIN_5, 0); // или дефайн LED_ON/LED_OFF

    // Включение светодиода
    GPIO_LED_On(&led);

    // Запуск моргания
    GPIO_LED_Blink_Start(&led, 500); // Период 500 мс

    // В основном цикле
    while (1) {
      GPIO_LED_Dynamic_Handle(&led);
    }
    @endcode
  * @{
  */

/* Инициализировать светодиод (структуру светодиода) */
OperationStatus GPIO_LED_Init(GPIO_LEDTypeDef *led, GPIO_TypeDef *GPIOx, uint32_t GPIO_PIN_X, BitState LED_On_State);
/* Включить светодиод */
OperationStatus GPIO_LED_On (GPIO_LEDTypeDef *led);
/* Выключить светодиод */
OperationStatus GPIO_LED_Off (GPIO_LEDTypeDef *led);
/* Переключить светодиод */
OperationStatus GPIO_LED_Toggle(GPIO_LEDTypeDef *led);
/* Выставить светодиод по переменной */
OperationStatus GPIO_LED_Set (GPIO_LEDTypeDef *led, uint8_t led_state);
/* Активировать моргание светодиодом */
OperationStatus GPIO_LED_Blink_Start (GPIO_LEDTypeDef *led, uint32_t period);
/* Активировать моргание светодиодом */
OperationStatus GPIO_LED_Fading_Start(GPIO_LEDTypeDef *led, uint32_t period);
/* Управление динамическими режимами свечения светодиода */
void GPIO_LED_Dynamic_Handle(GPIO_LEDTypeDef *led);

/** GPIO_LEDS
  * @}
  */
#endif /*__GPIO_H*/
