#ifndef __BUTTON_H__
#define __BUTTON_H__

#include "../common/def.h"

enum {btnPUSHED, btnRELEASED};        // 기본 시작은 0, 별도 숫자 지정 가능, 지정 다음부터 이어서 숫자
enum {NO_ACT, ACT_PUSH, ACT_RELEASE};

extern uint8_t btnPrev;

typedef struct _button {
    volatile uint8_t    *ddr;           // Register 에 입력, 읽기 등은 volatile 붙여서 최적화 금지
    volatile uint8_t    *pin;           // pin 이라는 Register 에서 값 읽기
    uint8_t             btnPin;
    uint8_t             prevState;
    uint8_t             btnEnabled;
} BUTTON;

void buttonInit(BUTTON *button, volatile uint8_t *ddr, volatile uint8_t *pin, uint8_t pinNumber);
uint8_t buttonGetState(BUTTON *button);

#endif /* __BUTTON_H__ */
// button.c
#include "button.h"

uint8_t btnPrev = 1;        // Button 4 Spin 을 Off 했을 때 이전 버튼 상태를 기억해서 표현하기 위한 변수

void buttonInit(BUTTON *button, volatile uint8_t *ddr, volatile uint8_t *pin, uint8_t pinNumber) {
    button->ddr = ddr;
    button->pin = pin;
    button->btnPin = pinNumber;
    button->btnEnabled = 0;
    button->prevState = btnRELEASED;       // 아무것도 안누른 초기화 상태
    *button->ddr &= ~(1 << button->btnPin);     // button pin을 input 설정
    // BUTTON_DDR &= ~(1 << pinNumber);
}

uint8_t buttonGetState(BUTTON *button) {    // BUTTON *button --> ddr, pin 주소 받기 위해 이용
    uint8_t curState = *button->pin & (1 << button->btnPin);        // 버튼 상태를 읽어옴, close 0, open 1(기본 상태)

    if ((curState == btnPUSHED) && (button->prevState == btnRELEASED)) {
        _delay_ms(50);                      // Debounce code
        button->prevState = btnPUSHED;      // Button 누름 상태 변경
        return ACT_PUSH;                    // Button 누름을 반환
    }
    else if ((curState != btnPUSHED) && (button->prevState == btnPUSHED)) {
        _delay_ms(50);                      // Debounce code
        button->prevState = btnRELEASED;    // Button 안누름 상태 변경
        return ACT_RELEASE;                 // Button 안누름을 반환
    }
    return NO_ACT;
}