#include "gd32f10x.h"
#include "fmc.h"


/*-------------------------------------------------*/
/*函数名：擦除FLASH                                */
/*参  数：start：擦除起始扇区   num：擦几个扇区    */
/*返回值：无                                       */
/*-------------------------------------------------*/
void GD32_EraseFlash(uint16_t start, uint16_t num)
{
	uint16_t i;        //用于for循环

	fmc_unlock();                                                       //解锁
	for(i=0;i<num;i++){                                                 //循环num次，一个扇区一个扇区的擦除
		fmc_page_erase((0x08000000 + start * 1024) + (1024 * i));       //擦除一个扇区
	}
	fmc_lock();                                                         //上锁
} 
/*---------------------------------------------------------------------*/
/*函数名：写入FLASH                                                    */
/*参  数：saddr：写入地址 wdata：写入数据指针  wnum：写入多少个字节    */
/*返回值：无                                                           */
/*---------------------------------------------------------------------*/
void GD32_WriteFlash(uint32_t saddr, uint32_t *wdata, uint32_t wnum)
{
	fmc_unlock();                          //解锁
	while(wnum){                           //循环写入，知道num等于0退出while，表示写入完毕
		fmc_word_program(saddr,*wdata);    //写入一个字（4个字节）
		wnum-=4;                           //写入字节数量-4
		saddr+=4;                          //写入地址+4
		wdata++;                           //写入数据的指针，往后挪动一次
	}
	fmc_lock();                            //上锁
}



/**
 * 读FLASH
 * @param  Address 地址
 * @param  Buffer  存放读取的数据
 * @param  Size    要读取的数据大小，单位字节
 * @return         读出成功的字节数
 */
uint32_t FLASH_Read(uint32_t Address, void *Buffer, uint32_t Size)
{
    uint32_t nread = Size;
    uint8_t* d = (uint8_t *)Buffer;
    const uint8_t* s = (const uint8_t *)Address;

    if (!Buffer || Address < GD32FLASH_BASE || Address >= GD32FLASH_END)
        return 0;

    while (nread >= sizeof(uint32_t) && (((uint32_t)s) <= (GD32FLASH_END - 4)))
    {
        *(volatile uint32_t *)d = *(volatile uint32_t *)s;
        d += sizeof(uint32_t);
        s += sizeof(uint32_t);
        nread -= sizeof(uint32_t);
    }

    while (nread && (((uint32_t)s) < GD32FLASH_END))
    {
        *d++ = *s++;
        nread--;
    }

    return Size - nread;
}

