/*
 * ch32v003 interrupts
 */

#include "ch32v00x_it.h"

#include <ch32v00x.h>

#include <stdint.h>

#include "device/btn.h"
#include "device/intr_out.h"
#include "device/irda.h"
#include "i2c_slave.h"



#define SYSTICK_COOLDOWN    3
uint8_t systick_timeout;



__attribute__((interrupt()))
void NMI_Handler(void)
{
    while (1);
}

__attribute__((interrupt()))
void HardFault_Handler(void)
{
    // hopefully we're running well enough to isolate the i2c bus

    // then reboot, because we shouldn't really be here

    while (1);
}

__attribute__((interrupt("WCH-Interrupt-fast")))
void SysTick_Handler(void)
{
    // ---- PROCESS UI AND COMMS

    btn_poll();         // button handler
    irda_process();     // irda timeout and retry

    SysTick->SR = 0;    // clear comparison flag


    // ---- DISABLE INTERRUPT

    // see if any buttons are currently pushed
    if ((BTN_PORT->INDR & BTN_PIN_MASK) != BTN_PIN_MASK) {
        // something is pushed, so keep the tick interrupt enabled
        systick_timeout = SYSTICK_COOLDOWN;
        return;
    }

    // see if irda is active

    // nothing is active, so shut down this interrupt source
    systick_timeout--;
    if (!systick_timeout) {
        NVIC_DisableIRQ(SysTicK_IRQn);
    }
}

__attribute__((interrupt()))
void EXTI7_0_IRQHandler(void)
{
    if (EXTI_GetITStatus(EXTI_Line3)) {
        // accelerometer has triggered.
        // let the master know right away.
        i2cs_append_flag(INT_ACCEL);
        EXTI_ClearITPendingBit(EXTI_Line3);
    }

    if (EXTI_GetITStatus(EXTI_Line0 | EXTI_Line4 | EXTI_Line5 | EXTI_Line6 | EXTI_Line7)) {
        // button is pushed.
        // enable main tick handler on button push.
        // tick handler will sense when it isn't needed and shut itself off.
        SysTick->SR = 0;
        systick_timeout = SYSTICK_COOLDOWN;
        NVIC_EnableIRQ(SysTicK_IRQn);
        EXTI_ClearITPendingBit(EXTI_Line0 | EXTI_Line4 | EXTI_Line5 | EXTI_Line6 | EXTI_Line7);
    }
}
