|
/******************************************************************************
|
* Copyright (C) 2014-2015 HangZhou SiZhu Co.,LTD.
|
*
|
*-----------------------------------------------------------------------------
|
* File: fm25v02.c
|
* Description: FRAM operation code
|
* Author: Lishoujian (867693272@qq.com)
|
* Date: Jan 8, 2015
|
*****************************************************************************/
|
|
/* ----------------------- Platform includes --------------------------------*/
|
|
#include "eeprom.h"
|
#include "spi.h"
|
#include "delay.h"
|
#include "gpio.h"
|
|
volatile uint8_t Fram_cs_flag = 0; //´æ´¢Æ¬Ñ¡±êÖ¾£¬ÒÔºóÔö¼ÓһƬ´æ´¢Ð¾Æ¬£¬ÓÃÓÚÑ¡Ôñ²Ù×÷ÄÇÒ»¿é´æ´¢£¬·Ç1ΪµÚ1¿é£¬1ΪµÚ2¿éÐÂÔöµÄ¡£
|
|
|
//static u16 WR_times=0;
|
//static u16 WR_times_suc=0;
|
|
|
void E2P_Ctrl_Gpio_Init(void)
|
{
|
CMU_PERCLK_SetableEx(PADCLK, ENABLE); //PADʱÖÓ£¨GPIO£©Ê¹Äܺ¯Êý
|
OutputIO(EEPROM_PWR_PORT,EEPROM_PWR_PIN,OUT_PUSHPULL);
|
OutputIO(EEPROM_CS1_PORT,EEPROM_CS1_PIN,OUT_PUSHPULL);
|
OutputIO(EEPROM_CS2_PORT,EEPROM_CS2_PIN,OUT_PUSHPULL);
|
CloseIO(EEPROM_WP_PORT,EEPROM_WP_PIN);
|
E2P_PWR_OFF;
|
EEPROM_CS_LOW;
|
EEPROM_CS_2_LOW;
|
}
|
|
|
|
|
typedef union
|
{
|
double dou;
|
uint8 data[8];
|
}double_un;
|
|
typedef union
|
{
|
float flo;
|
uint8 data[4];
|
}float_un;
|
|
|
typedef union
|
{
|
uint32 uio;
|
uint8 data[4];
|
}u32_un;
|
|
typedef union
|
{
|
uint16 uso;
|
uint8 data[2];
|
}u16_un;
|
|
|
void EEPROM_Wait_Busy(void)
|
{
|
while ((EEPROM_stat_read()&0x01)==0x01); //wait BUSY=0
|
}
|
|
/******************************************
|
* func: EEPROM_data_write
|
* desc: write 1 byte data to fram
|
* input:
|
* data - 1 byte data
|
* addr16 - destination address for write
|
* output: none
|
* return: none
|
*****************************************/
|
void EEPROM_data_write(uint8 data,uint32 addr16)
|
{
|
// uint8 haddr,laddr;
|
u32 addr_fit;
|
addr_fit = addr16 ;
|
// haddr = (addr16 >> 8) & 0x7f;//high 7 bit address
|
// laddr = (addr16 & 0xff); //low 8 bit address
|
|
// delay_us(10);
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_WREN);
|
EEPROM_CS_DISABLE;
|
|
// delay_us(10);
|
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_WRITE);
|
#ifndef EEPROM_ADDR_BYTES2
|
FM_ReadWriteByte((uint8_t)((addr_fit)>>16));
|
#endif
|
FM_ReadWriteByte((uint8_t)((addr_fit)>>8));
|
FM_ReadWriteByte((uint8_t)((addr_fit)));
|
FM_ReadWriteByte(data);
|
EEPROM_CS_DISABLE;
|
|
|
|
EEPROM_Wait_Busy();
|
|
|
}
|
|
/******************************************
|
* func: EEPROM_data_read
|
* desc: read 1 byte data from fram
|
* input:
|
* addr16 - destination address for read 1byte data
|
* output: none
|
* return: 1 byte data read from fram
|
*****************************************/
|
uint8 EEPROM_data_read(uint32 addr16)
|
{
|
uint8 data;
|
// uint8 haddr,laddr;
|
u32 addr_fit;
|
addr_fit = addr16 ;
|
// haddr = (addr16 >> 8) & 0x7f;//high 7 bit address
|
// laddr = (addr16 & 0xff); //low 8 bit address
|
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_READ);
|
#ifndef EEPROM_ADDR_BYTES2
|
FM_ReadWriteByte((uint8_t)(addr_fit>>16));
|
#endif
|
FM_ReadWriteByte((uint8_t)(addr_fit>>8));
|
FM_ReadWriteByte((uint8_t)(addr_fit));
|
data = FM_ReadWriteByte(0xff);//data = FM_ReadWriteByte(0xff);
|
EEPROM_CS_DISABLE;
|
|
return data;
|
}
|
|
/******************************************
|
* func: EEPROM_stat_write
|
* desc: write 1 byte status data to fram
|
* input:
|
* data - 1 byte state data to fram status register
|
* output: none
|
* return: none
|
*****************************************/
|
void EEPROM_stat_write(uint8 stat)
|
{
|
// delay_us(10);
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_WREN);
|
EEPROM_CS_DISABLE;
|
|
// delay_us(10);
|
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_WRSR);
|
FM_ReadWriteByte(stat);
|
EEPROM_CS_DISABLE;
|
|
}
|
|
/******************************************
|
* func: EEPROM_stat_read
|
* desc: read 1 byte status data from fram
|
* input: none
|
* output: none
|
* return: 1 byte status data read from fram
|
*****************************************/
|
uint8 EEPROM_stat_read(void)
|
{
|
uint8 stat;
|
|
delay_us(10);
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_RDSR);
|
stat = FM_ReadWriteByte(0xff);
|
EEPROM_CS_DISABLE;
|
|
return stat;
|
}
|
|
/******************************************
|
* func: EEPROM_sleep
|
* desc: take fram into sleep mode
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void EEPROM_sleep(void)
|
{
|
delay_us(10);
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_SLEEP);
|
EEPROM_CS_DISABLE;
|
}
|
|
|
/******************************************
|
* func: EEPROM_ID_read
|
* desc: read 9 byte ID data from fram
|
* input: none
|
* output: 9 byte ID data read from fram,write to dst
|
* return: none
|
*****************************************/
|
void EEPROM_ID_read(uint8 *dst)
|
{
|
uint8 i;
|
|
delay_us(10);
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_RDID);
|
for(i = 0;i < 9;i ++)
|
{
|
dst[i] = FM_ReadWriteByte(0xff);
|
}
|
EEPROM_CS_DISABLE;
|
}
|
|
|
|
/******************************************
|
* func: EEPROM_data_read_float
|
* desc: read float data from fram
|
* input:
|
* addr16 - destination address for read 1byte data
|
* output: none
|
* return:
|
*****************************************/
|
float EEPROM_data_read_float(uint32 addr16)
|
{
|
//float_un f;
|
float_un k;
|
k.data[0] = EEPROM_data_read(addr16);
|
k.data[1] = EEPROM_data_read(addr16+1);
|
k.data[2] = EEPROM_data_read(addr16+2);
|
k.data[3] = EEPROM_data_read(addr16+3);
|
return (k.flo);
|
}
|
|
/******************************************
|
* func: EEPROM_data_write_float
|
* desc: write float data from fram
|
* input:
|
* addr16 - destination address for read 1byte data
|
* output: none
|
* return:
|
*****************************************/
|
void EEPROM_data_write_float(uint32 addr16, float data)
|
{
|
float_un f;
|
f.flo = data;
|
|
EEPROM_MultipleWrite(f.data,addr16,4);
|
|
}
|
|
|
/******************************************
|
* func: EEPROM_data_read_float
|
* desc: read float data from fram
|
* input:
|
* addr16 - destination address for read 1byte data
|
* output: none
|
* return:
|
*****************************************/
|
double EEPROM_data_read_double(uint32 addr16)
|
{
|
double_un d;
|
d.data[0] = EEPROM_data_read(addr16);
|
d.data[1] = EEPROM_data_read(addr16+1);
|
d.data[2] = EEPROM_data_read(addr16+2);
|
d.data[3] = EEPROM_data_read(addr16+3);
|
d.data[4] = EEPROM_data_read(addr16+4);
|
d.data[5] = EEPROM_data_read(addr16+5);
|
d.data[6] = EEPROM_data_read(addr16+6);
|
d.data[7] = EEPROM_data_read(addr16+7);
|
if( (d.data[0]==0xff) && (d.data[1]==0xff)&&(d.data[2]==0xff) && (d.data[3]==0xff)&&(d.data[4]==0xff) && (d.data[5]==0xff)&&(d.data[6]==0xff) && (d.data[7]==0xff))
|
d.dou=0;
|
return (d.dou);
|
}
|
|
/******************************************
|
* func: EEPROM_data_read_float
|
* desc: read float data from fram
|
* input:
|
* addr16 - destination address for read 1byte data
|
* output: none
|
* return:
|
*****************************************/
|
void EEPROM_data_write_double(uint32 addr16, double data)
|
{
|
double_un d;
|
d.dou = data;
|
|
|
EEPROM_MultipleWrite(d.data,addr16,8);
|
|
}
|
|
|
/******************************************
|
* func: EEPROM_data_read_float
|
* desc: read float data from fram
|
* input:
|
* addr16 - destination address for read 1byte data
|
* output: none
|
* return:
|
*****************************************/
|
u32 EEPROM_data_read_uint32(uint32 addr16)
|
{
|
|
u32_un t;
|
t.data[0] = EEPROM_data_read(addr16);
|
t.data[1] = EEPROM_data_read(addr16+1);
|
t.data[2] = EEPROM_data_read(addr16+2);
|
t.data[3] = EEPROM_data_read(addr16+3);
|
return (t.uio);
|
}
|
|
/******************************************
|
* func: EEPROM_data_write_float
|
* desc: write float data from fram
|
* input:
|
* addr16 - destination address for read 1byte data
|
* output: none
|
* return:
|
*****************************************/
|
void EEPROM_data_write_uint32(uint32 addr16, uint32 data)
|
{
|
u32_un t;
|
t.uio = data;
|
|
EEPROM_MultipleWrite(t.data,addr16,4);
|
|
|
}
|
|
|
/******************************************
|
* func: EEPROM_data_read_float
|
* desc: read float data from fram
|
* input:
|
* addr16 - destination address for read 1byte data
|
* output: none
|
* return:
|
*****************************************/
|
u16 EEPROM_data_read_uint16(uint32 addr16)
|
{
|
|
u16_un t;
|
t.data[0] = EEPROM_data_read(addr16);
|
t.data[1] = EEPROM_data_read(addr16+1);
|
return (t.uso);
|
}
|
|
/******************************************
|
* func: EEPROM_data_write_float
|
* desc: write float data from fram
|
* input:
|
* addr16 - destination address for read 1byte data
|
* output: none
|
* return:
|
*****************************************/
|
void EEPROM_data_write_uint16(uint32 addr16, uint16 data)
|
{
|
u16_un t;
|
t.uso = data;
|
|
EEPROM_MultipleWrite(t.data,addr16,2);
|
|
}
|
|
|
uint8_t EEPROM_MultipleWrite(uint8_t *data,u32 addr,u16 bytes)
|
{
|
uint8_t flag;
|
uint8_t *ptr_data;
|
u16 i;
|
u32 addr_temp;
|
u32 index,byte_write_num_left,bytewrite;
|
//u32 banknum1,banknum2;
|
//ÏÈÅжÏÊý¾ÝÊÇ·ñ´¦ÓÚ256µÄÕâ¸öÇø¼äÄØ
|
if(bytes > 4000 )
|
return 0;
|
ptr_data = data;
|
flag = 0;
|
addr_temp = addr;
|
byte_write_num_left = bytes;
|
if(byte_write_num_left > 0) //ÐèҪдµÄÊý¾Ý»¹ÓÐÊ£Óà
|
{
|
|
index = (addr_temp/256) + 1;
|
if( ((index * 256) - addr_temp) >= byte_write_num_left)
|
{
|
bytewrite = byte_write_num_left;
|
|
}else
|
{
|
bytewrite = (index * 256) - addr_temp;
|
}
|
flag = 1;
|
}else
|
{
|
flag = 0;
|
|
}
|
|
|
|
while(flag)
|
{
|
|
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_WREN);
|
EEPROM_CS_DISABLE;
|
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_WRITE);
|
#ifndef EEPROM_ADDR_BYTES2
|
FM_ReadWriteByte((uint8_t)((addr_temp)>>16));
|
#endif
|
FM_ReadWriteByte((uint8_t)((addr_temp)>>8));
|
FM_ReadWriteByte((uint8_t)(addr_temp));
|
for(i = 0;i < bytewrite;i ++)
|
FM_ReadWriteByte(*ptr_data ++);
|
EEPROM_CS_DISABLE;
|
|
|
|
addr_temp = addr_temp + bytewrite;
|
byte_write_num_left = byte_write_num_left - bytewrite;
|
if(byte_write_num_left > 0) //ÐèҪдµÄÊý¾Ý»¹ÓÐÊ£Óà
|
{
|
|
index = (addr_temp/256) + 1;
|
if( ((index * 256) - addr_temp) >= byte_write_num_left)
|
{
|
bytewrite = byte_write_num_left;
|
|
}else
|
{
|
bytewrite = (index * 256) - addr_temp;
|
}
|
flag = 1;
|
}else
|
{
|
flag = 0;
|
|
}
|
EEPROM_Wait_Busy();
|
|
}
|
return 0;
|
}
|
|
|
void EEPROM_MultipleRead(uint8_t *data, u32 addr, u16 bytes)
|
{
|
u16 index;
|
|
EEPROM_CS_ENABLE;
|
FM_ReadWriteByte(FM_READ);
|
#ifndef EEPROM_ADDR_BYTES2
|
FM_ReadWriteByte((uint8_t)(addr>>16));
|
#endif
|
FM_ReadWriteByte((uint8_t)(addr>>8));
|
FM_ReadWriteByte((uint8_t)(addr));
|
for(index = 0;index < bytes;index ++)
|
data[index] = FM_ReadWriteByte(0xff);
|
EEPROM_CS_DISABLE;
|
EEPROM_Wait_Busy();
|
|
}
|
|
|
uint8_t EEPROM_MultipleWrite_CS_2(uint8_t *data,u32 addr,u16 bytes)
|
{
|
Fram_cs_flag = EEPROM_CS_2;
|
EEPROM_MultipleWrite(data, addr, bytes) ;
|
|
Fram_cs_flag = EEPROM_CS_1;
|
return 0;
|
}
|
|
uint8_t EEPROM_MultipleRead_CS_2(uint8_t *data,u32 addr,u16 bytes)
|
{
|
Fram_cs_flag = EEPROM_CS_2;
|
EEPROM_MultipleRead(data, addr, bytes) ;
|
|
Fram_cs_flag = EEPROM_CS_1;
|
return 0;
|
}
|
|
|
|
void EEPROM_test(void)
|
{
|
uint8_t u8_temp;
|
uint8_t u8_temp_s[256];
|
uint8_t u8_temp_s2[256];
|
static uint16_t WR_times = 0;
|
static uint16_t WR_times_suc = 0;
|
|
u16 count_i = 0;
|
|
E2P_Ctrl_Gpio_Init();
|
SPI3_Init();
|
EEPROM_CTRL_ENABLE;
|
|
EEPROM_MultipleRead(u8_temp_s2,1000,1); //?²âÊÔ·¢ÏÖµÚÒ»´Î²Ù×÷ÎÞЧ£¬ÐèÒªÏȲÙ×÷Ò»´Î£¬ºóÐø²Ù×÷¶¼ÊÇÕý³£µÄ¡£
|
|
for(count_i=0;count_i<256;count_i++)
|
{
|
u8_temp_s[count_i] = count_i;
|
u8_temp_s2[count_i] = 0;
|
}
|
EEPROM_CTRL_DISABLE;
|
|
delay_ms(10);
|
|
|
EEPROM_CTRL_ENABLE;
|
|
EEPROM_MultipleWrite(u8_temp_s,0,256);
|
delay_ms(1);
|
EEPROM_MultipleRead(u8_temp_s2,0,256);
|
|
|
EEPROM_CTRL_DISABLE;
|
|
|
E2P_Ctrl_Gpio_Init();
|
SPI3_Init();
|
|
for(count_i=0;count_i<256;count_i++)
|
{
|
u8_temp_s[count_i] = 255-count_i;
|
u8_temp_s2[count_i] = 0;
|
}
|
|
|
EEPROM_CTRL_ENABLE;
|
|
EEPROM_MultipleWrite(u8_temp_s,0,256);
|
delay_ms(1);
|
EEPROM_MultipleRead(u8_temp_s2,0,256);
|
|
EEPROM_CTRL_DISABLE;
|
|
|
|
|
E2P_Ctrl_Gpio_Init();
|
SPI3_Init();
|
|
for(count_i=0;count_i<256;count_i++)
|
{
|
u8_temp_s[count_i] = 8;
|
u8_temp_s2[count_i] = 0;
|
}
|
|
|
EEPROM_CTRL_ENABLE;
|
|
EEPROM_MultipleWrite(u8_temp_s,0,256);
|
delay_ms(1);
|
EEPROM_MultipleRead(u8_temp_s2,0,256);
|
|
EEPROM_CTRL_DISABLE;
|
|
// while(WR_times <1024)
|
// {
|
//
|
// EEPROM_MultipleWrite_CS_2(u8_temp_s,(WR_times * 256),256);
|
// delay_ms(1);
|
// for(count_i=0;count_i<256;count_i++)
|
// {
|
// u8_temp_s2[count_i] = 0;
|
// }
|
// EEPROM_MultipleRead_CS_2(u8_temp_s2,(WR_times * 256),256);
|
// WR_times ++;
|
//
|
// for(count_i=0;count_i<256;count_i++)
|
// {
|
// if(u8_temp_s[count_i] != u8_temp_s2[count_i])
|
// {
|
// break;
|
// }
|
// }
|
//
|
// if(count_i == 256)
|
// {
|
// WR_times_suc++;
|
// }
|
// delay_ms(998);
|
//
|
//
|
// }
|
|
|
|
|
|
while(1);
|
|
|
|
}
|