#include "optic_mag_driver.h"

volatile uint32_t g_optic_mag_value = 0;
volatile uint8_t  g_optic_mag_fresh = 0;

typedef enum {
    OPTIC_STATE_IDLE = 0,
    OPTIC_STATE_COLLECTING,
    OPTIC_STATE_WAIT_END,
} OpticState_t;

static UART_HandleTypeDef *s_huart;
static uint8_t             s_rx_byte;
static uint8_t             s_bcd_buf[OPTIC_MAG_DATA_BYTES];
static uint8_t             s_data_count;
static OpticState_t        s_state;

void OpticMag_Init(UART_HandleTypeDef *huart)
{
    s_huart      = huart;
    s_state      = OPTIC_STATE_IDLE;
    s_data_count = 0;
    HAL_UART_Receive_IT(s_huart, &s_rx_byte, 1);
}

void OpticMag_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart != s_huart) return;

    uint8_t byte = s_rx_byte;

    switch (s_state) {
        case OPTIC_STATE_IDLE:
            if (byte == OPTIC_MAG_FRAME_START) {
                s_data_count = 0;
                s_state = OPTIC_STATE_COLLECTING;
            }
            break;

        case OPTIC_STATE_COLLECTING:
            s_bcd_buf[s_data_count++] = byte;
            if (s_data_count == OPTIC_MAG_DATA_BYTES) {
                s_state = OPTIC_STATE_WAIT_END;
            }
            break;

        case OPTIC_STATE_WAIT_END:
            if (byte == OPTIC_MAG_FRAME_END) {
                // 取前9位BCD数字（忽略第10位），每字节低nibble为有效数字
                uint32_t value = 0;
                for (uint8_t i = 0; i < 9; i++) {
                    value = value * 10u + (s_bcd_buf[i] & 0x0Fu);
                }
                g_optic_mag_value = value;
                g_optic_mag_fresh = 1;
            }
            // 无论结束字节是否合法，均回到IDLE（非法帧直接丢弃）
            s_state = OPTIC_STATE_IDLE;
            break;
    }

    HAL_UART_Receive_IT(s_huart, &s_rx_byte, 1);
}

void OpticMag_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
    if (huart != s_huart) return;
    s_state = OPTIC_STATE_IDLE;
    HAL_UART_Receive_IT(s_huart, &s_rx_byte, 1);
}
