/** 
 * @file    gpio.h
 * @brief   GPIO module
 * @author  Kenny Tran
 * @date    Mar 01 2024
 * @version 0.0.1
 *
 * @section LICENSES
 * Copyright (C) Morgan Advanced Programmable Systems, Inc.
 */


#ifndef GPIO_H_
#define GPIO_H_


/*--------------------------------------------------------------------------------------------------
 * INCLUDE FILES
 *------------------------------------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>

#include "../lib/errno.h"


/*--------------------------------------------------------------------------------------------------
 * MACROS & CONSTANTS
 *------------------------------------------------------------------------------------------------*/


/*--------------------------------------------------------------------------------------------------
 * TYPE DEFINITIONS & ENUMERATIONS
 *------------------------------------------------------------------------------------------------*/
typedef enum GPIO_direction
{
    GPIO_DIRECTION_IN = 0,
    GPIO_DIRECTION_OUT
} GPIO_direction_e;

typedef enum GPIO_pull
{
    GPIO_PULLNONE = 0,
    GPIO_PULLDOWN,
    GPIO_PULLUP
} GPIO_pull_e;

typedef enum GPIO_init
{
    GPIO_INIT_LOW = 0,
    GPIO_INIT_HIGH,
} GPIO_init_e;

typedef enum GPIO_int_edge
{
    GPIO_INT_RISING_EDGE = 0,       /* GPIO interrupt to be triggered on pin rising edge. */
    GPIO_INT_FALLING_EDGE,          /* GPIO interrupt to be triggered on pin falling edge. */
    GPIO_INT_BOTH_EDGES,            /* GPIO interrupt to be triggered on pin rising or falling edge. */
    GPIO_INT_PL_LOW,                /* GPIO interrupt to be triggered on pin physical level low. */
    GPIO_INT_PL_HIGH,               /* GPIO interrupt to be triggered on pin physical level high. */
    GPIO_INT_STATE_CHANGE_LL_LOW,   /* GPIO interrupt to be triggered on pin state change to logical level 0. */
    GPIO_INT_STATE_CHANGE_LL_HIGH,  /* GPIO interrupt to be triggered on pin state change to logical level 1. */
    GPIO_INT_LL_LOW,                /* GPIO interrupt to be triggered on pin logical level 0. */
    GPIO_INT_LL_HIGH                /* GPIO interrupt to be triggered on pin logical level 1. */
} GPIO_int_edge_e;

typedef enum GPIO_pin
{
    GPIO_PIN_BUTTON_LEFT = 0,
    GPIO_PIN_BUTTON_CENTER,
    GPIO_PIN_BUTTON_RIGHT,
    GPIO_PIN_5V_ENABLE,
    GPIO_PIN_LED_RING_PWR,
    GPIO_PIN_LED_RING_LEVEL_SHIFT_ENABLE,
    GPIO_PIN_LED_RING_DIN,
    GPIO_PIN_BATTERY_CHECK_ENABLE,
    GPIO_PIN_IMU_INT,
    GPIO_PIN_CHARGER_STATUS,

    GPIO_PIN_COUNT
} GPIO_pin_e;

typedef void (*GPIO_cb_t) (void);


/*--------------------------------------------------------------------------------------------------
 * PUBLIC FUNCTION PROTOTYPES
 *------------------------------------------------------------------------------------------------*/
ERRNO_e GPIO_init (void);

ERRNO_e GPIO_cfg (GPIO_pin_e pin, GPIO_direction_e dir, GPIO_pull_e pull, GPIO_init_e init, GPIO_int_edge_e edge, GPIO_cb_t cb);

ERRNO_e GPIO_level_set (GPIO_pin_e pin, bool high);

bool GPIO_level_get (GPIO_pin_e pin);


#endif /* GPIO_H_ */

