#include <stdint.h>

#include "omw_gpio.h"

#define OMW_GPIO_FUN_CFG_INPUT      0

void omw_gpio_set_func(OMW_ENUM_GPIO_PIN pin, uint32_t cfg_val)
{
    volatile uint32_t * pcfg = (volatile uint32_t *)OMW_GPIO_CFG_BASE_ADDR;

    uint32_t wof = (pin >> 2);
    uint32_t bof = (pin & 3);
    uint32_t msk = (0xFF << (8 * bof));
    uint32_t rv  = *(pcfg + wof);

    rv &= (~msk);
    rv |= (cfg_val << (8 * bof));

    *(pcfg + wof) = rv;
}

void omw_gpio_set_func_ex(const struct gpio_cfg_tag * pcfg, int pins)
{
    for (int i = 0; i < pins; i++)
    {
        if (pcfg->id == 0xFF)
        {
            break;
        }

        omw_gpio_set_func(pcfg->id, pcfg->cfg);

        pcfg++;
    }
}

void omw_gpio_init(OMW_ENUM_GPIO_PIN pin,OMW_ENUM_GPIO_MODE mode,OMW_ENUM_GPIO_DRIVE_STRENTH drive_strenth)
{
    uint32_t cfg = mode + (drive_strenth<<3);
    omw_gpio_set_func(pin, cfg);
}

uint8_t omw_gpio_read_input_data(OMW_ENUM_GPIO_PIN pin)
{
    uint8_t bitstatus = 0x00;
	uint32_t flag = (0x01 << pin);
	if (((GPIO_INOUT->GPIO_I) & flag) != (uint32_t)RESET)
    {
        bitstatus = SET;
    }
    else
    {
        bitstatus = RESET;
    }
  return bitstatus;
}

uint32_t omw_gpio_read_input_data_all(void)
{
    return GPIO_INOUT->GPIO_I;
}

uint8_t omw_gpio_read_output_data(OMW_ENUM_GPIO_PIN pin)
{
    uint8_t bitstatus = 0x00;
	uint32_t flag = (0x01 << pin);
	if (((GPIO_INOUT->GPIO_O) & flag) != (uint32_t)RESET)
    {
        bitstatus = SET;
    }
    else
    {
        bitstatus = RESET;
    }
  return bitstatus;
}

uint32_t omw_gpio_read_output_data_all(void)
{
    return GPIO_INOUT->GPIO_O;
}


void omw_gpio_set_output_en(OMW_ENUM_GPIO_PIN pin,FunctionalState state)
{
	if(state != DISABLE)
		GPIO_INOUT ->GPIO_OE |= (ENABLE <<pin);
	else
		GPIO_INOUT ->GPIO_OE &= ~(ENABLE <<pin);
}

void omw_gpio_set_output(OMW_ENUM_GPIO_PIN pin, lineStatus flag)
{
	if(flag != LOW)
		GPIO_INOUT ->GPIO_O |= (HIGH <<pin);
	else
		GPIO_INOUT ->GPIO_O &= ~(HIGH <<pin);
}

void omw_gpio_set_it(OMW_ENUM_GPIO_PIN pin,OMW_GPIO_IT GPIO_IT,FunctionalState NewState)
{
	if (NewState != DISABLE)
		    *(uint32_t*)(GPIO_INTR_BASE + GPIO_IT) |= (uint32_t)(ENABLE << pin) ;
	else
			*(uint32_t*)(GPIO_INTR_BASE + GPIO_IT) &= ~((uint32_t)(ENABLE << pin)) ;
}

void omw_gpio_set_it_en(OMW_ENUM_GPIO_PIN pin,FunctionalState NewState)
{
	if(NewState != DISABLE)
		GPIO_INTR->GPIO_IE |=  (uint32_t) (ENABLE << pin);
	else
	    GPIO_INTR->GPIO_IE &=  ~((uint32_t)(ENABLE << pin));
}


ITStatus omw_gpio_get_it_status(OMW_ENUM_GPIO_PIN pin)
{
	ITStatus bitstatus = RESET;

	if((GPIO_INTR->GPIO_MIS & (0x01 << pin)) != RESET)
		bitstatus = SET;
	else
		bitstatus = RESET;
	return bitstatus;
}


void omw_gpio_it_flag_clr(OMW_ENUM_GPIO_PIN pin)
{
	  GPIO_INTR->GPIO_MIS |= (0x01 << pin);
	  GPIO_INTR ->GPIO_IS |= (0x01 << pin);
}

