/*
 * fml_flash.c
 *
 *  Created on: 2025年4月8日
 *      Author: 22332
 */

#include <stdio.h>
#include "cola_init.h"
#include "cola_device.h"
#include "cola_os.h"
#include "fml_flash.h"

uint8_t buff[8] = {1,2,3,4,5,6,0,0};
static cola_device_t *g_pDevflash = NULL;

#define VENDOR_CRC32_DEFAULT_VALUE      (0xF0F0F0F0)

/* Initialization of flash buffers */
ST_VENDOR_DATA gst_vendor_data;
ST_VENDOR_DATA gst_factory_data = {
		.crc32 = 0x0F0F0F0F,
		.mcu_upgrade_flag = 0x02,		///< MCU的升级标志
	    .screen_brightness= 0x02,		///< 屏幕亮度
		.PN_VERSION0= 0x02,
		.PN_VERSION1= 0x02,
		.PN_VERSION2= 0x02,
		.PN_VERSION3= 0x02,
		.PN_VERSION4= 0x02,
		.PN_VERSION5= 0x02,
		.HARDWARE_VERSION0= 0x01,
		.HARDWARE_VERSION1= 0x02,
		.HARDWARE_VERSION2= 0x03,
		.HARDWARE_VERSION3= 0x04,
		.HARDWARE_VERSION4= 0x08,
		.HARDWARE_VERSION5= 0x09,
		.SOFTWARE_VERSION0= 0x02,
		.SOFTWARE_VERSION1= 0x02,
		.SOFTWARE_VERSION2= 0x02,
		.SOFTWARE_VERSION3= 0x02,
		.SOFTWARE_VERSION4= 0x02,
		.SOFTWARE_VERSION5= 0x02,

};


uint32_t Utils_CRC32(const uint8_t *data, size_t len)
{
    uint32_t crc = 0xFFFFFFFF;
    uint8_t byte = 0;
    while (len--)
    {
        byte = *data++;
        crc ^= byte;
        for (int j = 0; j < 8; j++)
        {
            uint32_t mask = -(crc & 1);
            crc = (crc >> 1) ^ (0xEDB88320 & mask);
        }
    }
    return ~crc;
}
void vendor_factory_set(void)
{
    gst_vendor_data = gst_factory_data;
    vendor_data_save();
}
static uint8_t vendor_verify_data(ST_VENDOR_DATA *verify_data, uint16_t dataLen)
{
    uint32_t read_crc32 = verify_data->crc32;
    uint8_t mcu_upgrade_flag = verify_data->mcu_upgrade_flag;
    uint32_t verify_crc32 = 0;

    verify_data->mcu_upgrade_flag = 0xFF;
    verify_data->crc32 = VENDOR_CRC32_DEFAULT_VALUE;
    verify_crc32 = Utils_CRC32((const uint8_t *)verify_data, dataLen);
    verify_data->crc32 = read_crc32;
    verify_data->mcu_upgrade_flag = mcu_upgrade_flag;
    if (verify_crc32 != read_crc32)
    {
        return 1;
    }
    return 0;
}
void vendor_data_load(void)
{
	bool read_result = false;
    if (!g_pDevflash)
    {
        return;
    }
    for (uint8_t read_cnt = 0; read_cnt < 3; read_cnt++)
    {
       cola_device_read(g_pDevflash, 0, &gst_vendor_data, sizeof(gst_vendor_data));
       if (vendor_verify_data(&gst_vendor_data, sizeof(ST_VENDOR_DATA)) == 0)
       {
           read_result = true;
       }
   }
}
void vendor_data_save(void)
{

    if (!g_pDevflash)
    {
        return;
    }


    uint8_t mcu_upgrade_flag = gst_vendor_data.mcu_upgrade_flag;

    /* CRC32 calc. */
    gst_vendor_data.mcu_upgrade_flag = 0xFF;
    gst_vendor_data.crc32 = VENDOR_CRC32_DEFAULT_VALUE;
    gst_vendor_data.crc32 = Utils_CRC32((const uint8_t *)&gst_vendor_data, sizeof(gst_vendor_data));
    gst_vendor_data.mcu_upgrade_flag = mcu_upgrade_flag;
    cola_device_write(g_pDevflash, 0x10007C00, &gst_vendor_data, sizeof(gst_vendor_data));

}
void fml_flash_write(uint32_t address, uint8_t *buf)//write 8 byte
{
	cola_device_write(g_pDevflash,address,buf,0);

}
void fml_flash_read(uint32_t address, uint8_t *buf,uint8_t length)
{
	cola_device_read(g_pDevflash,address,buf,length);
}
void fml_flash_init(void)
{
	g_pDevflash = cola_device_find("FLASH");
    if(g_pDevflash)
        cola_device_open(g_pDevflash, 0);
    vendor_data_load();
}
