/*
 * ch32sub.c
 *
 * the sub MCU is responsible for the following:
 * - user buttons (complete handling / filtering)
 * - rgb chip hw enable / disable
 * - IrDA rx/tx and IrDA transciever enable / disable
 * - accelerometer hardware interrupt
 *
 *  Created on: Oct 11, 2024
 *      Author: true
 */

#include "ch32sub.h"
#include "port_intr.h"

// interrupt callbacks
#include "ui/btn.h"



volatile uint8_t intr_flag = 0;

static void (*flag_cb[8])() = {
        btn_intr,
        0,
        0,
        0,
        0,
        0,
        0,
        0
};



void ch32sub_isr()
{
    // we'll check what the MCU has to say when we're done processing
    intr_flag = 1;
}

void ch32sub_process()
{
    uint8_t flags;
    uint8_t i;

    if (intr_flag) {
        intr_flag = 0;
        flags = 1;

        // get interrupt flags
        i2c_read_reg16(SUB_I2C_ADDR, REG_INTR_FLAGS, &flags, 1);

        while (flags) {
            for (i = 0; i < 8; i++) {
                if (intr_flag & (1 << i)) {
                    if (flag_cb[i]) flag_cb[i]();
                    else {
                        // unhandled interrupt; clear it
                        // ch32sub_write_1b(REG_INTR_FLAGS, i << 1);
                    }
                }
            }

            // get interrupt flags (again)
            i2c_read_reg16(SUB_I2C_ADDR, REG_INTR_FLAGS, &flags, 1);
        }
    }
}

void ch32sub_init()
{
    // configure interrupt pin as pull-up
    // interrupt driven by CH32V003 is open drain active-lo
    GPIOB_ModeCfg(SUB_INTR_PIN, GPIO_ModeIN_PU);
    // configure interrupt to be rising edge
    GPIOB_ITModeCfg(SUB_INTR_PIN, GPIO_ITMode_RiseEdge);

    // register interrupt handler
    // note: this is handled as "high priority" within the interrupt handler now.
    // port_intr_cb_register(PORT_INTR_GPIOB, SUB_INTR_PIN_NR, ch32sub_isr);


}

// things to do
void ch32sub_read(uint16_t reg, uint8_t *dat, uint8_t len)
{
    i2c_read_reg16(SUB_I2C_ADDR, reg, dat, len);
}

void ch32sub_write(uint16_t reg, uint8_t *dat, uint8_t len)
{
    i2c_write_reg16(SUB_I2C_ADDR, reg, dat, len);
}

void ch32sub_write_1b(uint16_t reg, uint8_t dat)
{
    i2c_start();
    i2c_addr(SUB_I2C_ADDR, 0);
    i2c_wr(reg >> 8);
    i2c_wr(reg & 0xff);
    i2c_wr(dat);
    i2c_stop();
}

void ch32sub_rgb_hwen(uint8_t en)
{
    i2c_addr(SUB_I2C_ADDR, 1);
}
