/*
 * btn.c
 *
 * created Oct 13, 2024
 *
 * read and process buttons from sub MCU.
 * provide button handling support to application.
 *
 */

#include "btn.h"

#include "hw/ch32sub.h"



BtnSub btn[BTN_COUNT];

uint8_t btn_pushed;
uint8_t btn_held;



void btn_push_cb(uint8_t idx)
{
    btn_pushed |= (1 << idx);
    if (btn[idx].cb_push) btn[idx].cb_push(idx);
}

void btn_hold_cb(uint8_t idx)
{
    btn_held |= (1 << idx);
    if (btn[idx].cb_hold) btn[idx].cb_hold(idx);
}

void btn_release_cb(uint8_t idx)
{
    btn_pushed &= ~(1 << idx);
    btn_held   &= ~(1 << idx);
    if (btn[idx].cb_release) btn[idx].cb_release(idx);
}


void btn_commit_hold()
{
    uint8_t i, x;
    uint8_t val[BTN_COUNT*2];

    x = 0;
    for (i = 0; i < BTN_COUNT; i++) {
        val[x + 0x00] = btn[i].hold >> 8;
        val[x + 0x01] = btn[i].hold & 0xff;
        x += 2;
    }

    ch32sub_write(REG_BTN1_HOLD_HI, val, sizeof(val));

    x = 0;
    for (i = 0; i < BTN_COUNT; i++) {
        val[x + 0x00] = btn[i].repeat >> 8;
        val[x + 0x01] = btn[i].repeat & 0xff;
        x += 2;
    }

    ch32sub_write(REG_BTN1_REPEAT_HI, val, sizeof(val));
}


void btn_intr()
{
    uint8_t i;
    uint8_t btn_state[4]; // [9];
    // uint8_t *btn_mask = &btn_state[4];

    // get button data.
    ch32sub_read(REG_BTN_PUSHED_LATCHED, btn_state, sizeof(btn_state));

    // clear button interrupt flag
    ch32sub_write_1b(REG_INTR_FLAGS_CLEAR, INT_BTN);

    // process callbacks for new events
    for (i = 0; i < BTN_COUNT; i++) {
        if (btn_state[1] & (1 << i)) {
            btn_push_cb(i);
        }
        if (btn_state[2] & (1 << i)) {
            btn_hold_cb(i);
        }
        if (btn_state[3] & (1 << i)) {
            btn_release_cb(i);
        }
    }
}
