#include "bsp_buzzer.h"
#include "bsp_w25q.h"

/*开关控制电平，使用同一的电平控制方式*/
#define BUZZER_GPIO_ON   GPIO_PIN_SET
#define BUZZER_GPIO_OFF  GPIO_PIN_RESET

#define BUZZER_ON          HAL_GPIO_WritePin (BUZZER_GPIO_Port,    BUZZER_Pin,    BUZZER_GPIO_ON)
#define BUZZER_OFF         HAL_GPIO_WritePin (BUZZER_GPIO_Port,    BUZZER_Pin,    BUZZER_GPIO_OFF)

static void bsp_buzzer_init(void);
static void bsp_buzzer_task(void);
static void bsp_buzzer_set(u8 ch,u8 state);
static void bsp_buzzer_on(void);
static void bsp_buzzer_off(void);
static void bsp_buzzer_enable(void);
static void bsp_buzzer_disable(void);
static void bsp_buzzer_flash_data_load(void);

bsp_buzzer_t buzzer =
{
    .init        = bsp_buzzer_init,
    .task        = bsp_buzzer_task,
    .set.on      = bsp_buzzer_on,
    .set.off     = bsp_buzzer_off,
    .set.enable  = bsp_buzzer_enable,
    .set.disable = bsp_buzzer_disable,
};

bsp_buzzer_t *p_buzzer = &buzzer;


static bsp_buzzer_flash_data_t flash_data;

/*其他外设初始化后快速闪烁，提示初始化完成*/
static void bsp_buzzer_init(void)
{
    BUZZER_OFF;
    p_buzzer->p_flash_data = &flash_data;
    bsp_buzzer_flash_data_load();
}

static void bsp_buzzer_flash_data_save(void)
{
    // 擦除整个扇区（地址是扇区起始）
    w25q32_sector_erase(W25Q32_BUZZER_STATE_ADDR);
    w25q32.write(W25Q32_BUZZER_STATE_ADDR, (uint8_t*)&flash_data, sizeof(bsp_buzzer_flash_data_t));
}

static void bsp_buzzer_flash_data_load(void)
{
    w25q32.read(W25Q32_BUZZER_STATE_ADDR, (uint8_t*)&flash_data, sizeof(bsp_buzzer_flash_data_t));

    // 检查是否全为0xFF（首次使用）
    uint8_t *p = (uint8_t*)&flash_data;
    u8 all_ff = 1;
    for (u8 i = 0; i < sizeof(bsp_buzzer_flash_data_t); i++) {
        if (p[i] != 0xFF) {
            all_ff = 0;
            break;
        }
    }

    if (all_ff) {
        // 首次使用，默认关闭蜂鸣器
        flash_data.sw = USR_DISABLE;  
        bsp_buzzer_flash_data_save();
    }

    // 根据加载的状态设置蜂鸣器使能
    if (flash_data.sw == USR_ENABLE) {
        p_buzzer->p_flash_data->sw = flash_data.sw;
    }
}

static void bsp_buzzer_task(void)
{
    if(USR_DISABLE == p_buzzer->p_flash_data->sw)
    {
        BUZZER_OFF;
    }
    else if( USR_ON == p_buzzer->state)
    {
        BUZZER_ON;
    }
    else
    {
        BUZZER_OFF;
    }
}

static void bsp_buzzer_on(void)
{
    p_buzzer->state = USR_ON;
}
static void bsp_buzzer_off(void)
{
    p_buzzer->state = USR_OFF;
}
static void bsp_buzzer_enable(void)
{
    if(USR_ENABLE != p_buzzer->p_flash_data->sw)
    {
        p_buzzer->p_flash_data->sw = USR_ENABLE;
        bsp_buzzer_flash_data_save();
    }
}

static void bsp_buzzer_disable(void)
{
    if(USR_DISABLE != p_buzzer->p_flash_data->sw)
    {
        p_buzzer->p_flash_data->sw = USR_DISABLE;
        bsp_buzzer_flash_data_save();
    }
}
