/**
 * @file Drv_EEPROM.c
 * @author 吳星萍 (iris@e-besthealth.com)
 * @brief 寫一個Byte數據/讀一個Byte數據
 * @version 0.1
 * @date 2020-06-17
 *
 * @copyright BEST HEALTH ELECTRONIC INC (c) 2019
 *
 * Compiler Ver. : V3.57
 * IDE3000  Ver. : V8.03
 * MCU/CFG  Ver. : BH67F5362/1.1
 */

#include "Project_Global.h"
#include "BH67F5362.h"
#include "Drv_EEPROM.h"


#define MAX_EEPROM_ADDR	1024

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// ====================================================================================@
//                                  對外參數                                            @
// ====================================================================================@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
enum STATUS_t Read_EEPROMByte(unsigned int addr, unsigned char *data);
enum STATUS_t Read_EEPROMBuf(unsigned int addr,  unsigned char len,unsigned char* buf);
enum STATUS_t Write_EEPROMByte(unsigned int addr, unsigned char WriteData);
enum STATUS_t Write_EEPROMBuf(unsigned int addr, unsigned char len,const unsigned char* buf);


//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// ====================================================================================@
//                                  源代碼                                             @
// ====================================================================================@
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

/**
 * @brief 讀一個 Byte EEPROM 數據
 *
 * @param addr 地址(0~MAX_DATA_LEN)
 * @param 需要讀數據的長度
 * @return unsigned char
 */

enum STATUS_t Read_EEPROMByte(unsigned int addr, unsigned char *data)
{
	if (addr > MAX_EEPROM_ADDR)
	{
		return ERROR;
	}
	else
	{
		_eeah=addr>>8;
		_eeal = addr&0xff;
		_mp1h = 1;
		_mp1l = 0x40;
		asm("set [0x02].1");	// RDEN
		asm("set [0x02].0");	// RD
		asm("sz  [0x02].0");	// RD
		asm("jmp $-1");
		_iar1 = 0;
		*data = _eed;
		return SUCCESS;
	}
}
enum STATUS_t Read_EEPROMBuf(unsigned int addr, unsigned char len,unsigned char* buf)
{
    if((addr+len) > MAX_EEPROM_ADDR)
    {
        return ERROR;
    }
    unsigned char i = 0;
    for(i = 0; i<len; i++)
    {
        if(Read_EEPROMByte(addr, buf) != SUCCESS)
        {
        	return ERROR;
        }
        addr++;
        buf++;
    }
    return SUCCESS;
}
/**
 * @brief 寫一個 byte EEPROM 數據
 *
 * @param addr
 * @param WriteData
 * @warning WREN 和 WR 必須連續兩個指令寫入，所以必須關閉中斷，防止中斷打斷
 */
enum STATUS_t Write_EEPROMByte(unsigned int addr, unsigned char WriteData)
{
	if (addr > MAX_EEPROM_ADDR)
	{
		return ERROR;
	}
	else
	{
		unsigned char readData;
		bit EMI_Protect;
		EMI_Protect = _emi;
		_emi = 0;
		_mp1h = 1;
		_mp1l = 0x40;
		_eeah=addr>>8;
		_eeal = addr&0xff;
		_eed = WriteData;
		//_WREN與_WR需在連續的兩個指令週期內完成
		asm("set [0x02].3");	// WREN
		asm("set [0x02].2");	// WR
		asm("sz  [0x02].2");	// WR
		asm("jmp $-1");
		_iar1 = 0; //disable WREN
		_emi = EMI_Protect;
		if (Read_EEPROMByte(addr, &readData) != SUCCESS)
		{
			return ERROR;
		}
		if (readData != WriteData)
		{
			return ERROR;
		}
		else
		{
			return SUCCESS;
		}
	}
}
enum STATUS_t Write_EEPROMBuf(unsigned int addr, unsigned char len,const unsigned char* buf)
{
	if((addr+len) > MAX_EEPROM_ADDR)
	{
		return ERROR;
	}
	unsigned char i= 0;
	for(i= 0; i<len; i++)
	{
		if(Write_EEPROMByte(addr, *buf) != SUCCESS)
		{
			return ERROR;
		}
		addr++;
		buf++;
	}
	return SUCCESS;
}