/*
 * gpio.h
 * cp1251 ru
 *  Created on: 21 ���. 2016 �.
 *      Author: alexrayne <alexraynepe196@gmail.com>
  ------------------------------------------------------------------------
    Copyright (c) alexrayne

   All rights reserved.
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions are met:
   - Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.
   - Neither the name of ARM nor the names of its contributors may be used
     to endorse or promote products derived from this software without
     specific prior written permission.
   *
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. *
 */

#ifndef _CARDIO_HAL_H
#define _CARDIO_HAL_H

#include <stdbool.h>

#include "mcu_gpio.h"
#include "mcu_rcc.h"

#include <c_compat.h>

#ifdef __cplusplus
extern "C" {
#endif



#define GPIO_PORT_NO(port)  (((uint32_t)port-GPIOA_BASE)>>10)

void gpio_conf_pin(GPIO_TypeDef* port, unsigned pins);
void gpio_conf_pout(GPIO_TypeDef* port, unsigned pins);
void gpio_conf_pout_oc(GPIO_TypeDef* port, unsigned pins);
void gpio_conf_func(const GPIOFUNC_INIT* x);
void gpio_conf_out(const PIN_INIT* x);
void gpio_conf_speed(GPIO_TypeDef* port, unsigned pins, unsigned speed);
void gpio_conf_port_style(GPIO_TypeDef* port, unsigned pins, unsigned style );

INLINE
void gpio_conf1pin_speed(GPIO_TypeDef* port, unsigned pin, unsigned speed){
    LL_GPIO_SetPinSpeed(port, pin, speed);
}



// функции GPIO_XXX -  инлайнятся, и предназначены для использования с константами
//          которые могут оптимизироваться во время компиляции

// функции gpio_xxx -  предназначены для использования с переменными непредсказуемыми
//          которые оптимизироваться во время компиляции не могут


INLINE
uint32_t gpio_pins(GPIO_TypeDef* port, unsigned pins){
  return GPIO_ReadInputData(port) & pins;
}

INLINE
uint32_t gpio_pouts(GPIO_TypeDef* port, unsigned pins){
  return GPIO_Bits(port, pins);
}

INLINE
void gpio_on(GPIO_TypeDef* port, unsigned pins){
    GPIO_SetBits(port, pins);
}

INLINE
uint32_t gpio_set(GPIO_TypeDef* port, unsigned pins, unsigned mask){
  uint32_t res = GPIO_Bits(port, ~mask) | (pins & mask);
  GPIO_WriteBit(port, res);
  return res;
}

INLINE
void gpio_off(GPIO_TypeDef* port, unsigned pins){
    GPIO_ResetBits(port, pins);
}

#define GPIO_PINS(port, pin)    gpio_pins(port, pin)
#define GPIO_POUTS(port, pin)   gpio_pouts(port, pin)
#define GPIO_ON(port, pin)      gpio_on(port, pin)
#define GPIO_OFF(port, pin)     gpio_off(port, pin)
#define GPIO_SET(port, pin, mask)   gpio_set(port, pin, mask)


#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
// назначает функцию GPIO IN для x
void gpio_conf_pin(const GPIOFUNC_INIT* x);

// назначает пинам функцию
void gpio_set_func(const GPIOFUNC_INIT* x);

// \return - функция первого пина в pins
//         - 0= PORT_FUNC_PORT если pins пусто
PORT_FUNC_TypeDef gpio_func(const GPIOFUNC_INIT* x);

void gpio_on(const PIN_INIT* x);
void gpio_off(const PIN_INIT* x);
uint32_t gpio_pins(const PIN_INIT* x);
void gpio_conf_in(const PIN_INIT* x, unsigned pins);
#endif

#endif
