#include "internal_flash.h"

/**Declaring functions**/
uint os_spiflash_read(void *buf,u32 adder,uint len);    //系统自带读函数
void os_spiflash_program(void *buf,u32 addr,uint len);  //系统自带写函数，一次最多写是256字节，不可跨页写
void os_spiflash_erase(u32 addr);                       //系统自带擦除函数，4K擦除
/***********************/
AT(.com_text.data)
u8 erase_buff[4096]={0x00};     //擦除函数使用buff，一次擦除4K，故最大定义4K就可以
AT(.com_text.data)
u8 rbuff[4096]={0x00};          //读flash函数使用buff，可自己定义大小
AT(.com_text.data)
u8 wbuff[4096]={0x00};          //写flash函数使用buff，可自己定义大小
/***********************/

/**一次最大能擦除4K的大小**/
void internal_flash_erase_partial(uint32_t start_address, uint32_t size)
{
    uint32_t sector_size = 4096; // 最小擦除单位为4KB
    // 计算要操作的扇区起始地址
    uint32_t sector_start_address = start_address & ~(sector_size - 1);
    // 读取整个扇区到缓冲区
    os_spiflash_read(erase_buff,sector_start_address, sector_size);
    // 设置要擦除的部分为0xFF
    memset(erase_buff + (start_address - sector_start_address), 0xFF, size);
    // 擦除该扇区
    os_spiflash_erase(sector_start_address);
    // 将修改后的数据写回Flash
    internal_flash_write( erase_buff,sector_start_address, sector_size);
}
/**擦除后才可进行写操作，不擦除写不进去**/
void internal_flash_write( uint8_t* data,uint32_t address, uint32_t length)
{
    uint32_t page_size = 256;                   // 每次写入的字节数
    uint32_t pages = length / page_size;        // 计算需要写的页数
    uint32_t remaining = length % page_size;    // 计算剩余的字节数
    // 写完整的页
    for (uint32_t i = 0; i < pages; i++) {
        os_spiflash_program(data + i * page_size,address + i * page_size , page_size);
    }
    // 写剩余的字节
    if (remaining > 0) {
        uint8_t buffer[page_size];
        memset(buffer, 0xFF, page_size);        // 假设Flash未写入状态是0xFF
        memcpy(buffer, data + pages * page_size, remaining);
        os_spiflash_program(buffer,address + pages * page_size, page_size);
    }
}

//设置蓝牙名称，可不用在download软件进行设置
u8 *bt_Name="GW3323-%02X%02X";
flash_Save mySavePara;              //保存参数结构体
#define bt_write_area  0x100FA000   //使用flash备份区最后的4K数据进行数据的保存
void set_bluetooth_name(void)
{
    u8 ack_Mac[6];
    bt_get_local_bd_addr(ack_Mac);
//    printf("SPP_Mac: %2X %2X %2X %2X %2X %2X\n",ack_Mac[0],ack_Mac[1],ack_Mac[2],ack_Mac[3],ack_Mac[4],ack_Mac[5]);
    sprintf(xcfg_cb.bt_name,bt_Name,ack_Mac[4],ack_Mac[5]);

    ble_get_local_bd_addr(ack_Mac);
//    printf("BLE_Mac: %2X %2X %2X %2X %2X %2X\n",ack_Mac[0],ack_Mac[1],ack_Mac[2],ack_Mac[3],ack_Mac[4],ack_Mac[5]);
    sprintf(xcfg_cb.le_name,bt_Name,ack_Mac[4],ack_Mac[5]);

    printf("------------------------------\n");
    printf("spp_name:%s\n",xcfg_cb.bt_name);
    printf("ble_name:%s\n",xcfg_cb.le_name);

/**保存数据到flash**/
    memcpy(&mySavePara.bt_name,&xcfg_cb.bt_name,sizeof(xcfg_cb.bt_name));
    memcpy(&mySavePara.le_name,&xcfg_cb.le_name,sizeof(xcfg_cb.bt_name));

    internal_flash_erase_partial(bt_write_area,sizeof(flash_Save));
    internal_flash_write((uint8_t*)&mySavePara,bt_write_area,sizeof(flash_Save));

    printf("%d \n",sizeof(flash_Save));
    printf("%s \n",mySavePara.bt_name);
    printf("%s \n",mySavePara.le_name);
}

//读取保存的蓝牙参数
void read_bluetooth_name(void)
{
	os_spiflash_read((uint8_t*)&mySavePara,bt_write_area,sizeof(flash_Save));
    printf("%s \n",mySavePara.bt_name);
    printf("%s \n",mySavePara.le_name);
    memcpy(xcfg_cb.bt_name,mySavePara.bt_name,sizeof(mySavePara.bt_name));
    memcpy(xcfg_cb.le_name,mySavePara.le_name,sizeof(mySavePara.le_name));
}

//flash数据读写
#define write_read_area     0x100E4000  //备份区地址为0x10080000，加上程序的400K为 0x100E4000
#define write_read_size     1000        //读写数据大小
u8 g_ucMcuId[32];                       //保存ID号
void internal_flash_examples(void)
{
    spiflash_get_id(g_ucMcuId); //获取芯片的唯一ID号
    printf("mcu ID:");
    for(int i = 0;i<16;i++)
        printf("%02X ",g_ucMcuId[i]);
    printf("\r\n");

    for(uint32_t i = 0; i < write_read_size; i++)
    {
        wbuff[i]=i;
        printf("%02x ", wbuff[i]);
        if ((i + 1) % 16 == 0)
        {
            printf("\n");
        }
    }
    printf("\n");

    internal_flash_erase_partial(write_read_area,write_read_size);  //擦除的地址与大小
    internal_flash_write(wbuff,write_read_area,write_read_size);
    os_spiflash_read(rbuff,write_read_area,write_read_size);

    for(uint32_t i = 0; i < write_read_size; i++)
    {
        printf("%02x ", rbuff[i]);
        if ((i + 1) % 16 == 0)
        {
            printf("\n");
        }
    }
    printf("\n");
}

