#include <stdint.h>
#include <stdbool.h>
typedef enum
{
UHAL_STATUS_OK,
UHAL_STATUS_ERROR
} uhal_status_t;
struct _uhal_gpio_t;
typedef enum
{
UHAL_GPIO_GROUP_A,
UHAL_GPIO_GROUP_B,
UHAL_GPIO_GROUP_C,
UHAL_GPIO_GROUP_D,
UHAL_GPIO_GROUP_E,
UHAL_GPIO_GROUP_F,
UHAL_GPIO_GROUP_G,
UHAL_GPIO_GROUP_H,
UHAL_GPIO_GROUP_I,
UHAL_GPIO_GROUP_J,
UHAL_GPIO_GROUP_K,
UHAL_GPIO_GROUP_L,
UHAL_GPIO_GROUP_M,
UHAL_GPIO_GROUP_N,
UHAL_GPIO_GROUP_O,
UHAL_GPIO_GROUP_P,
UHAL_GPIO_GROUP_Q,
UHAL_GPIO_GROUP_R,
UHAL_GPIO_GROUP_S,
UHAL_GPIO_GROUP_T,
UHAL_GPIO_GROUP_U,
UHAL_GPIO_GROUP_V,
UHAL_GPIO_GROUP_W,
UHAL_GPIO_GROUP_X,
UHAL_GPIO_GROUP_Y,
UHAL_GPIO_GROUP_Z
} uhal_gpio_group_t;
typedef enum
{
UHAL_GPIO_MODE_INPUT,
UHAL_GPIO_MODE_OUTPUT
} uhal_gpio_mode_t;
typedef enum
{
UHAL_GPIO_PULL_RESISTOR_NONE,
UHAL_GPIO_PULL_RESISTOR_PULL_UP,
UHAL_GPIO_PULL_RESISTOR_PULL_DOWN
} uhal_gpio_pull_resisitor_t;
typedef enum
{
UHAL_GPIO_STATE_LOW,
UHAL_GPIO_STATE_HIGH
} uhal_gpio_state_t;
typedef struct
{
uint8_t pin;
uhal_gpio_group_t group;
uhal_gpio_mode_t mode;
uhal_gpio_pull_resisitor_t pull_resistor;
struct _uhal_gpio_t* deprived;
} uhal_gpio_t;
uhal_status_t uhal_gpio_init(uhal_gpio_t* gpio);
uhal_status_t uhal_gpio_write(uhal_gpio_t* gpio, uhal_gpio_state_t state);
uhal_status_t uhal_gpio_toggle(uhal_gpio_t* gpio);
uhal_status_t uhal_gpio_read(uhal_gpio_t* gpio, uhal_gpio_state_t* state);
#include <avr/io.h>
#include <stdio.h>
struct _uhal_gpio_t
{
volatile uint8_t reg_pin;
volatile uint8_t reg_ddr;
volatile uint8_t reg_port;
};
uhal_status_t uhal_gpio_init(uhal_gpio_t* gpio)
{
if (gpio == NULL)
{
return UHAL_STATUS_ERROR;
}
if (gpio->pin > 7)
{
return UHAL_STATUS_ERROR;
}
switch(gpio->group)
{
case UHAL_GPIO_GROUP_B: gpio->deprived = (struct _uhal_gpio_t*) &PINB ; break;
default: return UHAL_STATUS_ERROR;
}
if (gpio->mode == UHAL_GPIO_MODE_OUTPUT)
{
gpio->deprived->reg_ddr |= (1 << gpio->pin);
}
else
{
gpio->deprived->reg_ddr &= ~(1 << gpio->pin);
if (gpio->pull_resistor == UHAL_GPIO_PULL_RESISTOR_PULL_UP)
{
gpio->deprived->reg_port |= (1 << gpio->pin);
}
}
return UHAL_STATUS_OK;
}
uhal_status_t uhal_gpio_write(uhal_gpio_t* gpio, uhal_gpio_state_t state)
{
if(gpio == NULL)
{
return UHAL_STATUS_ERROR;
}
if(gpio->mode == UHAL_GPIO_MODE_INPUT)
{
return UHAL_STATUS_ERROR;
}
switch (state)
{
case UHAL_GPIO_STATE_LOW: gpio->deprived->reg_port &= ~(1 << gpio->pin); break;
case UHAL_GPIO_STATE_HIGH: gpio->deprived->reg_port |= (1 << gpio->pin); break;
default: return UHAL_STATUS_ERROR;
}
return UHAL_STATUS_OK;
}
uhal_status_t uhal_gpio_toggle(uhal_gpio_t* gpio)
{
if(gpio == NULL)
{
return UHAL_STATUS_ERROR;
}
if(gpio->mode == UHAL_GPIO_MODE_INPUT)
{
return UHAL_STATUS_ERROR;
}
gpio->deprived->reg_port ^= (1 << gpio->pin);
return UHAL_STATUS_OK;
}
uhal_status_t uhal_gpio_read(uhal_gpio_t* gpio, uhal_gpio_state_t* state)
{
if(gpio == NULL)
{
return UHAL_STATUS_ERROR;
}
if(gpio->mode == UHAL_GPIO_MODE_OUTPUT)
{
return UHAL_STATUS_ERROR;
}
*state = ((gpio->deprived->reg_pin >> gpio->pin) & 1) == 0 ? UHAL_GPIO_STATE_LOW : UHAL_GPIO_STATE_HIGH;
return UHAL_STATUS_OK;
}
int main(void){
uhal_gpio_t pin = {
.pin = 2,
.group = UHAL_GPIO_GROUP_B,
.mode = UHAL_GPIO_MODE_OUTPUT,
.pull_resistor = UHAL_GPIO_PULL_RESISTOR_NONE
};
uhal_gpio_init(&pin);
uhal_gpio_write(&pin, UHAL_GPIO_STATE_HIGH);
for(;;){
}
}