/****************************************************************************** * 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); }