/*********************************************************
*Copyright (C), 2017, Shanghai Eastsoft Microelectronics Co., Ltd.
*文件名:  flash.c
*作  者:  AE Team
*版  本:  V1.01
*日  期:  2021/05/14
*描  述:  FLASH模块程序
*备  注:  本软件仅供学习和演示使用，对用户直接引用代码所带来的风险或后果不承担任何法律责任。
**********************************************************/
#include "e2rom.h"
#include "spi.h"
#include "uart.h"
#include "string.h"

/*********************************************************
函数名: void e2rom_DO_Init(void);
描  述: 初始化e2rom的DO管脚为普通IO
输入值: 无
输出值: 无
返回值: 无
**********************************************************/
static void e2rom_DO_Init(void)
{
    GPIO_InitStruType x;

    /* MISO Pin设置为GPIO，用于判断相应 */
    x.GPIO_Signal = GPIO_Pin_Signal_Digital;
    x.GPIO_Direction = GPIO_Dir_In;
    x.GPIO_Func = GPIO_Func_0;
    x.GPIO_PUEN = GPIO_PUE_Input_Disable;
    x.GPIO_PDEN = GPIO_PDE_Input_Enable;
    GPIO_Init(GPIOA, SPI_MISO, &x);
}

/*********************************************************
函数名: void e2rom_DO_DefaultInit(void);
描  述: 初始化e2rom的DO管脚为SPI的MISO
输入值: 无
输出值: 无
返回值: 无
**********************************************************/
static void e2rom_DO_DefaultInit(void)
{
    GPIO_InitStruType x;

    /* MISO Pin设置为GPIO，用于判断相应 */
    x.GPIO_Signal = GPIO_Pin_Signal_Digital;
    x.GPIO_Direction = GPIO_Dir_In;
    x.GPIO_Func = GPIO_Func_3;
    x.GPIO_PUEN = GPIO_PUE_Input_Disable;
    x.GPIO_PDEN = GPIO_PDE_Input_Enable;
    GPIO_Init(GPIOA, SPI_MISO, &x);
}

/*********************************************************
函数名: void E2rom_Ewen(void)
描  述: EEPROM写使能
输入值: 无
输出值: 无
返回值: 无
**********************************************************/
static void E2rom_Ewen(void)
{
    CS_SET;

    SPI_SendByte(0x02);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    SPI_SendByte(0x60);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    CS_RESET;
}

/*********************************************************
函数名: void E2rom_Ewds(void)
描  述: EEPROM写禁止
输入值: 无
输出值: 无
返回值: 无
**********************************************************/
static void E2rom_Ewds(void)
{
    CS_SET;

    SPI_SendByte(0x02);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    SPI_SendByte(0x00);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    CS_RESET;
}

/*********************************************************
函数名: void E2rom_init(void)
描  述: 初始化E2ROM模块
输入值: 无
输出值: 无
返回值: 无
**********************************************************/
void E2rom_init(void)
{
    SPI_GPIO_Init();
    UARTInit();
}

/*********************************************************
函数名: void E2romReadData(uint8_t addr, uint8_t *buf)
描  述: SPI读数据，连续字节读出(查询模式)
输入值: addr—地址
输出值: buf—接收数据缓存
返回值: 无
**********************************************************/
void E2romReadData(uint8_t addr, uint8_t *buf)
{
    CS_SET;

    SPI_SendByte(0x03);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    SPI_SendByte(addr);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    SPI_RecEnable();

    while (SPI_GetFlagStatus(SPI_Flag_RB));

    SPI_SendByte(0);

    while (SPI_GetFlagStatus(SPI_Flag_RB) == RESET);

    *buf = SPI_RecByte();

    CS_RESET;

    SPI_RecDisable();
}

/*********************************************************
函数名: void E2romWriteData(uint8_t addr, uint8_t buf)
描  述: E2rom写数据，逐个字节编程
输入值: addr—地址
        buf—待发送数据
输出值: 无
返回值: 无
**********************************************************/
void E2romWriteData(uint8_t addr, uint8_t buf)
{
    e2rom_DO_Init();

    E2rom_Ewen();
    Delay100us(1);

    CS_SET;

    SPI_SendByte(0x02);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    SPI_SendByte(0x80 | addr);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    SPI_SendByte(buf);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    CS_RESET;
    CS_SET;

    while ((GPIO_ReadBit(GPIOA, SPI_MISO)) == 0);

    CS_RESET;

    e2rom_DO_DefaultInit();

    Delay100us(1);
    E2rom_Ewds();
}

/*********************************************************
函数名: void E2romEraseAll(void)
描  述: E2ROM擦除全片（填充0xFF）
输入值: 无
输出值: 无
返回值: 无
**********************************************************/
void E2romEraseAll(void)
{
    e2rom_DO_Init();

    E2rom_Ewen();
    Delay100us(1);

    CS_SET;

    SPI_SendByte(0x02);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    SPI_SendByte(0x40);

    while (SPI_GetFlagStatus(SPI_Flag_IDLE) == RESET);

    CS_RESET;
    CS_RESET;
    CS_SET;

    while ((GPIO_ReadBit(GPIOA, SPI_MISO)) == 0);

    CS_RESET;

    e2rom_DO_DefaultInit();

    Delay100us(1);
    E2rom_Ewds();
}
